Compare commits

..

1 Commits

Author SHA1 Message Date
Brian DeHamer 60a047b675 oci compat mode input arg
Signed-off-by: Brian DeHamer <bdehamer@github.com>
2025-04-10 10:34:46 -07:00
22 changed files with 3978 additions and 15648 deletions
+10
View File
@@ -0,0 +1,10 @@
rules:
document-end: disable
document-start:
level: warning
present: false
line-length:
level: warning
max: 80
allow-non-breakable-words: true
allow-non-breakable-inline-mappings: true
@@ -1,14 +1,13 @@
import eslint from '@eslint/js'
import importplugin from 'eslint-plugin-import'
import jestplugin from 'eslint-plugin-jest'
import path from 'node:path'
import tseslint from 'typescript-eslint'
export default tseslint.config(
// Ignore non-project files
{
name: 'ignore',
ignores: ['.github', 'dist', 'coverage', '**/*.json', 'jest.setup.js', 'eslint.config.mjs']
ignores: ['.github', 'dist', 'coverage', '**/*.json', 'jest.setup.js']
},
// Use recommended rules from ESLint, TypeScript, and other plugins
eslint.configs.recommended,
@@ -22,7 +21,7 @@ export default tseslint.config(
languageOptions: {
ecmaVersion: 2023,
parserOptions: {
project: [ './tsconfig.lint.json' ]
project: ['./.github/linters/tsconfig.json', './tsconfig.json']
}
},
rules: {
+9
View File
@@ -0,0 +1,9 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "../../tsconfig.json",
"compilerOptions": {
"noEmit": true
},
"include": ["../../__tests__/**/*", "../../src/**/*"],
"exclude": ["../../dist", "../../node_modules", "../../coverage", "*.json"]
}
+1 -1
View File
@@ -28,7 +28,7 @@ jobs:
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v5
uses: actions/checkout@v4
- name: Setup Node.js
id: setup-node
+2 -2
View File
@@ -21,7 +21,7 @@ jobs:
steps:
- name: Checkout
id: checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Setup Node.js
id: setup-node
@@ -58,7 +58,7 @@ jobs:
steps:
- name: Checkout
id: checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Calculate subject digest
id: subject
env:
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v5
uses: actions/checkout@v4
- name: Initialize CodeQL
id: initialize
+50
View File
@@ -0,0 +1,50 @@
name: Lint Codebase
on:
pull_request:
branches:
- main
push:
branches:
- main
permissions:
contents: read
packages: read
statuses: write
jobs:
lint:
name: Lint Codebase
runs-on: ubuntu-latest
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
id: setup-node
uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: npm
- name: Install Dependencies
id: install
run: npm ci
- name: Lint Codebase
id: super-linter
uses: super-linter/super-linter/slim@v7.2.1
env:
DEFAULT_BRANCH: main
FILTER_REGEX_EXCLUDE: dist/**/*
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TYPESCRIPT_DEFAULT_STYLE: prettier
VALIDATE_ALL_CODEBASE: true
VALIDATE_JAVASCRIPT_STANDARD: false
VALIDATE_TYPESCRIPT_STANDARD: false
VALIDATE_JSCPD: false
@@ -0,0 +1,22 @@
name: 'Publish Immutable Action Version'
on:
release:
types: [published]
permissions: {}
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
packages: write
steps:
- name: Checking out
uses: actions/checkout@v4
- name: Publish
id: publish
uses: actions/publish-immutable-action@v0.0.4
+1 -1
View File
@@ -1 +1 @@
24.5.0
20.6.0
-6
View File
@@ -18,12 +18,6 @@ Once the attestation has been created and signed, it will be uploaded to the GH
attestations API and associated with the repository from which the workflow was
initiated.
When an attestation is created, the attestation is stored on the local
filesystem used by the runner. For each attestation created, the filesystem path
will be appended to the file `${RUNNER_TEMP}/created_attestation_paths.txt`.
This can be used to gather all attestations created by all jobs during a the
workflow.
Attestations can be verified using the [`attestation` command in the GitHub
CLI][5].
+2 -23
View File
@@ -473,13 +473,6 @@ badline
'187dcd1506a170337415589ff00c8743f19d41cc31fca246c2739dfd450d0b9d'
}
})
expect(subjects).toContainEqual({
name: 'demo_0.0.1_darwin_arm64',
digest: {
sha512:
'5d8b4751ef31f9440d843fcfa4e53ca2e25b1cb1f13fd355fdc7c24b41fe645293291ea9297ba3989078abb77ebbaac66be073618a9e4974dbd0361881d4c718'
}
})
})
})
})
@@ -487,8 +480,8 @@ badline
describe('when specifying a subject checksums string', () => {
const checksums = `
f861e68a080799ca83104630b56abb90d8dbcc5f8b5a8639cb691e269838f29e demo_0.0.1_linux_386
187dcd1506a170337415589ff00c8743f19d41cc31fca246c2739dfd450d0b9d *demo_0.0.1_linux_amd64
9ecbf449e286a8a8748c161c52aa28b6b2fc64ab86f94161c5d1b3abc18156c5 demo_0.0.1_linux_arm64`
187dcd1506a170337415589ff00c8743f19d41cc31fca246c2739dfd450d0b9d demo_0.0.1_linux_amd64
9ecbf449e286a8a8748c161c52aa28b6b2fc64ab86f94161c5d1b3abc18156c5 demo_0.0.1_linux_arm64`
it('returns the multiple subjects', async () => {
const inputs: SubjectInputs = {
@@ -507,20 +500,6 @@ f861e68a080799ca83104630b56abb90d8dbcc5f8b5a8639cb691e269838f29e demo_0.0.1_lin
'f861e68a080799ca83104630b56abb90d8dbcc5f8b5a8639cb691e269838f29e'
}
})
expect(subjects).toContainEqual({
name: 'demo_0.0.1_linux_amd64',
digest: {
sha256:
'187dcd1506a170337415589ff00c8743f19d41cc31fca246c2739dfd450d0b9d'
}
})
expect(subjects).toContainEqual({
name: 'demo_0.0.1_linux_arm64',
digest: {
sha256:
'9ecbf449e286a8a8748c161c52aa28b6b2fc64ab86f94161c5d1b3abc18156c5'
}
})
})
})
+1 -1
View File
@@ -73,5 +73,5 @@ outputs:
description: 'The URL for the attestation summary.'
runs:
using: node24
using: node20
main: ./dist/index.js
Generated Vendored
+343 -10460
View File
File diff suppressed because it is too large Load Diff
+3504 -5091
View File
File diff suppressed because it is too large Load Diff
+20 -20
View File
@@ -1,7 +1,7 @@
{
"name": "actions/attest",
"description": "Generate signed attestations for workflow artifacts",
"version": "3.0.0",
"version": "2.2.1",
"author": "",
"private": true,
"homepage": "https://github.com/actions/attest",
@@ -20,15 +20,15 @@
".": "./dist/index.js"
},
"engines": {
"node": ">=24"
"node": ">=20"
},
"scripts": {
"bundle": "npm run format:write && npm run package",
"ci-test": "jest",
"format:write": "prettier --write **/*.ts",
"format:check": "prettier --check **/*.ts",
"lint:eslint": "npx eslint",
"lint:markdown": "npx markdownlint --config .markdown-lint.yml \"*.md\"",
"lint:eslint": "npx eslint . -c ./.github/linters/eslint.config.mjs",
"lint:markdown": "npx markdownlint --config .github/linters/.markdown-lint.yml \"*.md\"",
"lint": "npm run lint:eslint && npm run lint:markdown",
"package": "ncc build src/index.ts --license licenses.txt",
"package:watch": "npm run package -- --watch",
@@ -71,29 +71,29 @@
"dependencies": {
"@actions/attest": "^1.6.0",
"@actions/core": "^1.11.1",
"@actions/github": "^6.0.1",
"@actions/github": "^6.0.0",
"@actions/glob": "^0.5.0",
"@sigstore/oci": "^0.6.0",
"@sigstore/oci": "^0.4.0",
"csv-parse": "^5.6.0"
},
"devDependencies": {
"@eslint/js": "^9.34.0",
"@sigstore/mock": "^0.11.0",
"@types/jest": "^30.0.0",
"@eslint/js": "^9.23.0",
"@sigstore/mock": "^0.10.0",
"@types/jest": "^29.5.14",
"@types/make-fetch-happen": "^10.0.4",
"@types/node": "^24.3.0",
"@types/node": "^22.13.14",
"@vercel/ncc": "^0.38.3",
"eslint": "^9.34.0",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jest": "^29.0.1",
"jest": "^30.0.5",
"eslint": "^9.23.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jest": "^28.11.0",
"jest": "^29.7.0",
"js-yaml": "^4.1.0",
"markdownlint-cli": "^0.45.0",
"markdownlint-cli": "^0.44.0",
"nock": "^13.5.6",
"prettier": "^3.6.2",
"ts-jest": "^29.4.1",
"typescript": "^5.9.2",
"typescript-eslint": "^8.41.0",
"undici": "^5.29.0"
"prettier": "^3.5.3",
"ts-jest": "^29.3.1",
"typescript": "^5.8.2",
"typescript-eslint": "^8.29.0",
"undici": "^5.28.5"
}
}
+2
View File
@@ -17,6 +17,7 @@ export const createAttestation = async (
sigstoreInstance: SigstoreInstance
pushToRegistry: boolean
githubToken: string
ociCompatMode: boolean
}
): Promise<AttestResult> => {
// Sign provenance w/ Sigstore
@@ -43,6 +44,7 @@ export const createAttestation = async (
'dev.sigstore.bundle.content': 'dsse-envelope',
'dev.sigstore.bundle.predicateType': predicate.type
},
compatibility: opts.ociCompatMode,
fetchOpts: { timeout: OCI_TIMEOUT, retry: OCI_RETRY }
})
+3
View File
@@ -18,6 +18,9 @@ const inputs: RunInputs = {
// undocumented -- not part of public interface
privateSigning: ['true', 'True', 'TRUE', '1'].includes(
core.getInput('private-signing')
),
ociCompatMode: ['true', 'True', 'TRUE', '1'].includes(
core.getInput('oci-compatibility-mode')
)
}
+3 -21
View File
@@ -16,7 +16,6 @@ import {
import type { Subject } from '@actions/attest'
const ATTESTATION_FILE_NAME = 'attestation.json'
const ATTESTATION_PATHS_FILE_NAME = 'created_attestation_paths.txt'
export type RunInputs = SubjectInputs &
PredicateInputs & {
@@ -24,6 +23,7 @@ export type RunInputs = SubjectInputs &
githubToken: string
showSummary: boolean
privateSigning: boolean
ociCompatMode: boolean
}
/* istanbul ignore next */
@@ -69,7 +69,8 @@ export async function run(inputs: RunInputs): Promise<void> {
const att = await createAttestation(subjects, predicate, {
sigstoreInstance,
pushToRegistry: inputs.pushToRegistry,
githubToken: inputs.githubToken
githubToken: inputs.githubToken,
ociCompatMode: inputs.ociCompatMode
})
logAttestation(subjects, att, sigstoreInstance)
@@ -80,28 +81,11 @@ export async function run(inputs: RunInputs): Promise<void> {
flag: 'a'
})
const baseDir = process.env.RUNNER_TEMP
/* istanbul ignore else */
if (baseDir) {
const outputSummaryPath = path.join(baseDir, ATTESTATION_PATHS_FILE_NAME)
// Append the output path to the attestations paths file
fs.appendFileSync(outputSummaryPath, outputPath + os.EOL, {
encoding: 'utf-8',
flag: 'a'
})
} else {
core.warning(
'RUNNER_TEMP environment variable is not set. Cannot write attestation paths file.'
)
}
/* istanbul ignore else */
if (att.attestationID) {
core.setOutput('attestation-id', att.attestationID)
core.setOutput('attestation-url', attestationURL(att.attestationID))
}
/* istanbul ignore else */
if (inputs.showSummary) {
await logSummary(att)
}
@@ -159,7 +143,6 @@ const logAttestation = (
core.info(`${SEARCH_PUBLIC_GOOD_URL}?logIndex=${attestation.tlogID}`)
}
/* istanbul ignore else */
if (attestation.attestationID) {
core.info(style.highlight('Attestation uploaded to repository'))
core.info(attestationURL(attestation.attestationID))
@@ -175,7 +158,6 @@ const logAttestation = (
const logSummary = async (attestation: AttestResult): Promise<void> => {
const { attestationID } = attestation
/* istanbul ignore else */
if (attestationID) {
const url = attestationURL(attestationID)
core.summary.addHeading('Attestation Created', 3)
+2 -8
View File
@@ -181,14 +181,8 @@ const getSubjectFromChecksumsString = (checksums: string): Subject[] => {
continue
}
// It's common for checksum records to have a leading flag character before
// the artifact name. It will be either a '*' or a space.
const flag_and_name = record.slice(delimIndex + 1)
const name =
flag_and_name.startsWith('*') || flag_and_name.startsWith(' ')
? flag_and_name.slice(1)
: flag_and_name
// Swallow the type identifier character at the beginning of the name
const name = record.slice(delimIndex + 2)
const digest = record.slice(0, delimIndex)
if (!HEX_STRING_RE.test(digest)) {
-1
View File
@@ -5,7 +5,6 @@
"module": "NodeNext",
"rootDir": "./src",
"moduleResolution": "NodeNext",
"isolatedModules": true,
"baseUrl": "./",
"sourceMap": true,
"outDir": "./dist",
-9
View File
@@ -1,9 +0,0 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true
},
"include": ["./__tests__/**/*", "./src/**/*"],
"exclude": ["./dist", "./node_modules", "./coverage", "*.json"]
}