limit attestation subject count (#53)
Signed-off-by: Brian DeHamer <bdehamer@github.com>
This commit is contained in:
@@ -65,7 +65,7 @@ See [action.yml](action.yml)
|
||||
with:
|
||||
# Path to the artifact serving as the subject of the attestation. Must
|
||||
# specify exactly one of "subject-path" or "subject-digest". May contain
|
||||
# a glob pattern or list of paths.
|
||||
# a glob pattern or list of paths (total subject count cannot exceed 64).
|
||||
subject-path:
|
||||
|
||||
# SHA256 digest of the subject for the attestation. Must be in the form
|
||||
|
||||
@@ -5,12 +5,14 @@
|
||||
* Specifically, the inputs listed in `action.yml` should be set as environment
|
||||
* variables following the pattern `INPUT_<INPUT_NAME>`.
|
||||
*/
|
||||
|
||||
import * as core from '@actions/core'
|
||||
import * as github from '@actions/github'
|
||||
import { mockFulcio, mockRekor, mockTSA } from '@sigstore/mock'
|
||||
import * as oci from '@sigstore/oci'
|
||||
import fs from 'fs/promises'
|
||||
import nock from 'nock'
|
||||
import os from 'os'
|
||||
import path from 'path'
|
||||
import { MockAgent, setGlobalDispatcher } from 'undici'
|
||||
import { SEARCH_PUBLIC_GOOD_URL } from '../src/endpoints'
|
||||
import * as main from '../src/main'
|
||||
@@ -286,6 +288,52 @@ describe('action', () => {
|
||||
expect(setFailedMock).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('when too many subjects are specified', () => {
|
||||
let dir = ''
|
||||
|
||||
beforeEach(async () => {
|
||||
const filename = 'subject'
|
||||
const content = 'file content'
|
||||
|
||||
// Set-up temp directory
|
||||
const tmpDir = await fs.realpath(os.tmpdir())
|
||||
dir = await fs.mkdtemp(tmpDir + path.sep)
|
||||
|
||||
// Add files for glob testing
|
||||
for (let i = 0; i < 65; i++) {
|
||||
await fs.writeFile(path.join(dir, `${filename}-${i}`), content)
|
||||
}
|
||||
|
||||
// Set the GH context with private repository visibility and a repo owner.
|
||||
setGHContext({
|
||||
payload: { repository: { visibility: 'private' } },
|
||||
repo: { owner: 'foo', repo: 'bar' }
|
||||
})
|
||||
|
||||
// Mock the action's inputs
|
||||
getInputMock.mockImplementation(
|
||||
mockInput({
|
||||
predicate: '{}',
|
||||
'subject-path': path.join(dir, `${filename}-*`)
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
// Clean-up temp directory
|
||||
await fs.rm(dir, { recursive: true })
|
||||
})
|
||||
|
||||
it('sets a failed status', async () => {
|
||||
await main.run()
|
||||
|
||||
expect(runMock).toHaveReturned()
|
||||
expect(setFailedMock).toHaveBeenCalledWith(
|
||||
'Too many subjects specified. The maximum number of subjects is 64.'
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
function mockInput(inputs: Record<string, string>): typeof core.getInput {
|
||||
|
||||
@@ -10,7 +10,7 @@ inputs:
|
||||
description: >
|
||||
Path to the artifact serving as the subject of the attestation. Must
|
||||
specify exactly one of "subject-path" or "subject-digest". May contain a
|
||||
glob pattern or list of paths.
|
||||
glob pattern or list of paths (total subject count cannot exceed 64).
|
||||
required: false
|
||||
subject-digest:
|
||||
description: >
|
||||
|
||||
6
dist/index.js
generated
vendored
6
dist/index.js
generated
vendored
@@ -79644,6 +79644,7 @@ const subject_1 = __nccwpck_require__(95206);
|
||||
const COLOR_CYAN = '\x1B[36m';
|
||||
const COLOR_DEFAULT = '\x1B[39m';
|
||||
const ATTESTATION_FILE_NAME = 'attestation.jsonl';
|
||||
const MAX_SUBJECT_COUNT = 64;
|
||||
/**
|
||||
* The main function for the action.
|
||||
* @returns {Promise<void>} Resolves when the action is complete.
|
||||
@@ -79661,8 +79662,11 @@ async function run() {
|
||||
if (!process.env.ACTIONS_ID_TOKEN_REQUEST_URL) {
|
||||
throw new Error('missing "id-token" permission. Please add "permissions: id-token: write" to your workflow.');
|
||||
}
|
||||
// Calculate subject from inputs and generate provenance
|
||||
// Gather list of subjets
|
||||
const subjects = await (0, subject_1.subjectFromInputs)();
|
||||
if (subjects.length > MAX_SUBJECT_COUNT) {
|
||||
throw new Error(`Too many subjects specified. The maximum number of subjects is ${MAX_SUBJECT_COUNT}.`);
|
||||
}
|
||||
const predicate = (0, predicate_1.predicateFromInputs)();
|
||||
const outputPath = path_1.default.join(tempDir(), ATTESTATION_FILE_NAME);
|
||||
// Generate attestations for each subject serially
|
||||
|
||||
10
src/main.ts
10
src/main.ts
@@ -16,6 +16,8 @@ const COLOR_CYAN = '\x1B[36m'
|
||||
const COLOR_DEFAULT = '\x1B[39m'
|
||||
const ATTESTATION_FILE_NAME = 'attestation.jsonl'
|
||||
|
||||
const MAX_SUBJECT_COUNT = 64
|
||||
|
||||
/**
|
||||
* The main function for the action.
|
||||
* @returns {Promise<void>} Resolves when the action is complete.
|
||||
@@ -38,8 +40,14 @@ export async function run(): Promise<void> {
|
||||
)
|
||||
}
|
||||
|
||||
// Calculate subject from inputs and generate provenance
|
||||
// Gather list of subjets
|
||||
const subjects = await subjectFromInputs()
|
||||
if (subjects.length > MAX_SUBJECT_COUNT) {
|
||||
throw new Error(
|
||||
`Too many subjects specified. The maximum number of subjects is ${MAX_SUBJECT_COUNT}.`
|
||||
)
|
||||
}
|
||||
|
||||
const predicate = predicateFromInputs()
|
||||
const outputPath = path.join(tempDir(), ATTESTATION_FILE_NAME)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user