add new subject-version input (#364)

Signed-off-by: Brian DeHamer <bdehamer@github.com>
This commit is contained in:
Brian DeHamer
2026-02-26 12:38:12 -08:00
committed by GitHub
parent 8b290b8d86
commit ec072a1cb2
10 changed files with 41 additions and 7 deletions

View File

@@ -30,6 +30,7 @@ describe('index', () => {
'subject-name': 'my-artifact',
'subject-digest': '',
'subject-checksums': '',
'subject-version': '',
'predicate-type': 'https://example.com/predicate',
predicate: '{}',
'predicate-path': '',
@@ -57,6 +58,7 @@ describe('index', () => {
subjectName: 'my-artifact',
subjectDigest: '',
subjectChecksums: '',
subjectVersion: '',
predicateType: 'https://example.com/predicate',
predicate: '{}',
predicatePath: '',

View File

@@ -145,7 +145,8 @@ describe('createAttestation', () => {
const storageOpts = {
...defaultOpts,
pushToRegistry: true,
createStorageRecord: true
createStorageRecord: true,
subjectVersion: '1.2.3'
}
it('should create storage record when enabled and owner is org', async () => {
@@ -157,10 +158,27 @@ describe('createAttestation', () => {
storageOpts
)
expect(mockCreateStorageRecord).toHaveBeenCalled()
expect(mockCreateStorageRecord).toHaveBeenCalledWith(
expect.objectContaining({ version: '1.2.3' }),
expect.anything(),
expect.anything()
)
expect(result.storageRecordIds).toEqual([12345])
})
it('should omit version from storage record when subjectVersion is empty', async () => {
const subjects = [TEST_SUBJECT_WITH_REGISTRY]
const opts = { ...storageOpts, subjectVersion: '' }
await createAttestation(subjects, TEST_PREDICATE, opts)
expect(mockCreateStorageRecord).toHaveBeenCalledWith(
expect.objectContaining({ version: undefined }),
expect.anything(),
expect.anything()
)
})
it('should skip storage record when owner is User', async () => {
mockGetOctokit.mockReturnValue(createOctokitMock('User'))
const subjects = [TEST_SUBJECT_WITH_REGISTRY]

View File

@@ -101,6 +101,7 @@ const defaultInputs: RunInputs = {
subjectChecksums: '',
pushToRegistry: false,
createStorageRecord: false,
subjectVersion: '',
showSummary: false,
githubToken: 'test-token',
privateSigning: false

View File

@@ -30,6 +30,11 @@ inputs:
attestation. Must specify exactly one of "subject-path", "subject-digest",
or "subject-checksums".
required: false
subject-version:
description: >
Version of the subject for the attestation. Only used when
"push-to-registry" and "create-storage-record" are both set to true.
required: false
sbom-path:
description: >
Path to the JSON-formatted SBOM file (SPDX or CycloneDX) to attest.

5
dist/index.js generated vendored
View File

@@ -120899,7 +120899,8 @@ const createAttestation = async (subjects, predicate, opts) => {
const registryUrl = getRegistryURL(subject.name);
const artifactOpts = {
name: subject.name,
digest: subjectDigest
digest: subjectDigest,
version: opts.subjectVersion || undefined
};
const packageRegistryOpts = {
registryUrl
@@ -121157,6 +121158,7 @@ async function run(inputs) {
sigstoreInstance,
pushToRegistry: inputs.pushToRegistry,
createStorageRecord: inputs.createStorageRecord,
subjectVersion: inputs.subjectVersion,
githubToken: inputs.githubToken
});
logAttestation(subjects, att, sigstoreInstance);
@@ -121298,6 +121300,7 @@ const inputs = {
predicatePath: getInput('predicate-path'),
pushToRegistry: getBooleanInput('push-to-registry'),
createStorageRecord: getBooleanInput('create-storage-record'),
subjectVersion: getInput('subject-version'),
showSummary: getBooleanInput('show-summary'),
githubToken: getInput('github-token'),
// undocumented -- not part of public interface

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "actions/attest",
"version": "4.0.0",
"version": "4.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "actions/attest",
"version": "4.0.0",
"version": "4.1.0",
"license": "MIT",
"dependencies": {
"@actions/attest": "^3.2.0",

View File

@@ -1,7 +1,7 @@
{
"name": "actions/attest",
"description": "Generate signed attestations for workflow artifacts",
"version": "4.0.0",
"version": "4.1.0",
"author": "",
"private": true,
"type": "module",

View File

@@ -26,6 +26,7 @@ export const createAttestation = async (
sigstoreInstance: SigstoreInstance
pushToRegistry: boolean
createStorageRecord: boolean
subjectVersion?: string
githubToken: string
}
): Promise<AttestResult> => {
@@ -77,7 +78,8 @@ export const createAttestation = async (
const registryUrl = getRegistryURL(subject.name)
const artifactOpts = {
name: subject.name,
digest: subjectDigest
digest: subjectDigest,
version: opts.subjectVersion || undefined
}
const packageRegistryOpts = {
registryUrl

View File

@@ -15,6 +15,7 @@ const inputs: RunInputs = {
predicatePath: core.getInput('predicate-path'),
pushToRegistry: core.getBooleanInput('push-to-registry'),
createStorageRecord: core.getBooleanInput('create-storage-record'),
subjectVersion: core.getInput('subject-version'),
showSummary: core.getBooleanInput('show-summary'),
githubToken: core.getInput('github-token'),
// undocumented -- not part of public interface

View File

@@ -35,6 +35,7 @@ export type RunInputs = SubjectInputs &
SBOMInputs & {
pushToRegistry: boolean
createStorageRecord: boolean
subjectVersion: string
githubToken: string
showSummary: boolean
privateSigning: boolean
@@ -97,6 +98,7 @@ export async function run(inputs: RunInputs): Promise<void> {
sigstoreInstance,
pushToRegistry: inputs.pushToRegistry,
createStorageRecord: inputs.createStorageRecord,
subjectVersion: inputs.subjectVersion,
githubToken: inputs.githubToken
})