Skip to content

Commit 67cf9cc

Browse files
Merge pull request #2 from davidalmeidac/chore/ci-pin-action-shas
chore(ci): pin GitHub Actions to commit SHAs + add lint script
2 parents 3343bbb + 04572cc commit 67cf9cc

12 files changed

Lines changed: 227 additions & 16 deletions

File tree

.github/dependabot.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "github-actions"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
groups:
8+
actions:
9+
patterns:
10+
- "*"
11+
commit-message:
12+
prefix: "chore(ci)"

.github/workflows/java-ci.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,17 @@ jobs:
3333
java: ["17", "21"]
3434

3535
steps:
36-
- uses: actions/checkout@v4
36+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
3737

3838
- name: Set up JDK ${{ matrix.java }}
39-
uses: actions/setup-java@v4
39+
uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4.8.0
4040
with:
4141
distribution: temurin
4242
java-version: ${{ matrix.java }}
4343
cache: maven
4444

4545
- name: Set up Node 22 (for cross-stack vectors)
46-
uses: actions/setup-node@v4
46+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
4747
with:
4848
node-version: 22
4949

@@ -66,7 +66,7 @@ jobs:
6666

6767
- name: Upload surefire reports on failure
6868
if: failure()
69-
uses: actions/upload-artifact@v4
69+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
7070
with:
7171
name: surefire-${{ matrix.os }}-jdk${{ matrix.java }}
7272
path: java/**/target/surefire-reports/

.github/workflows/java-release.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ jobs:
2020
environment: maven-central
2121

2222
steps:
23-
- uses: actions/checkout@v4
23+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
2424

2525
- name: Set up JDK 21
26-
uses: actions/setup-java@v4
26+
uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4.8.0
2727
with:
2828
distribution: temurin
2929
java-version: "21"
@@ -35,7 +35,7 @@ jobs:
3535
gpg-passphrase: MAVEN_GPG_PASSPHRASE
3636

3737
- name: Set up Node 22 (for cross-stack vectors)
38-
uses: actions/setup-node@v4
38+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
3939
with:
4040
node-version: 22
4141

@@ -63,7 +63,7 @@ jobs:
6363
run: mvn -B -ntp -Prelease deploy -DskipTests
6464

6565
- name: Create GitHub Release
66-
uses: softprops/action-gh-release@v2
66+
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2
6767
with:
6868
generate_release_notes: true
6969
name: "Java ${{ github.ref_name }}"

.github/workflows/node-ci.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,13 @@ jobs:
3535
os: [ubuntu-latest, windows-latest, macos-latest]
3636

3737
steps:
38-
- uses: actions/checkout@v4
38+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
3939

40-
- uses: actions/setup-node@v4
40+
- name: Lint workflow pinning
41+
working-directory: ${{ github.workspace }}
42+
run: node node/scripts/lint-workflows.mjs
43+
44+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
4145
with:
4246
node-version: ${{ matrix.node }}
4347
cache: npm

.github/workflows/node-release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ jobs:
2929
environment: npm-publish
3030

3131
steps:
32-
- uses: actions/checkout@v4
32+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
3333

34-
- uses: actions/setup-node@v4
34+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
3535
with:
3636
node-version: 22
3737
cache: npm

.github/workflows/pages.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,16 @@ jobs:
2626
url: ${{ steps.deployment.outputs.page_url }}
2727
runs-on: ubuntu-latest
2828
steps:
29-
- uses: actions/checkout@v4
29+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
3030

3131
- name: Configure Pages
32-
uses: actions/configure-pages@v5
32+
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0
3333

3434
- name: Upload site artifact
35-
uses: actions/upload-pages-artifact@v3
35+
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1
3636
with:
3737
path: site
3838

3939
- name: Deploy
4040
id: deployment
41-
uses: actions/deploy-pages@v4
41+
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5

node/scripts/lint-workflows.mjs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/usr/bin/env node
2+
/**
3+
* Lint .github/workflows/*.yml — every `uses:` line MUST pin to a
4+
* 40-char commit SHA, with an optional trailing comment.
5+
*
6+
* Exit codes:
7+
* 0 all uses: lines pinned (or no non-local uses: lines found)
8+
* 1 one or more lines fail the pin regex (prints file:line:offender to stderr)
9+
* 2 unexpected error (e.g. workflows dir missing)
10+
*
11+
* Environment:
12+
* LINT_WORKFLOWS_DIR override the directory to lint (default: .github/workflows)
13+
* useful for unit tests pointing at fixture dirs
14+
*/
15+
16+
import { readFileSync, readdirSync } from 'node:fs';
17+
import { join, resolve } from 'node:path';
18+
19+
const WORKFLOWS_DIR = process.env.LINT_WORKFLOWS_DIR ?? '.github/workflows';
20+
21+
// Matches a ref ending with @<40-hex-chars> — tested against the extracted
22+
// ref value after stripping quotes, not the raw line.
23+
const PIN_RE = /@[a-f0-9]{40}$/;
24+
25+
// Matches a uses: line (list-item form or map-value form, quoted or unquoted).
26+
// Group 1: optional open quote, Group 2: the reference value, Group 3: trailing comment
27+
const USES_RE = /^\s*-?\s*uses:\s*(['"]?)([^'";\s#]+)\1(\s*#.*)?$/;
28+
29+
let failed = 0;
30+
31+
try {
32+
const dir = resolve(WORKFLOWS_DIR);
33+
const files = readdirSync(dir).filter(
34+
(f) => f.endsWith('.yml') || f.endsWith('.yaml'),
35+
);
36+
37+
for (const f of files) {
38+
const filePath = join(dir, f);
39+
const lines = readFileSync(filePath, 'utf8').split(/\r?\n/);
40+
41+
lines.forEach((line, idx) => {
42+
const m = line.match(USES_RE);
43+
if (!m) return;
44+
45+
const ref = m[2];
46+
// Local actions (./.github/actions/...) and docker images are not
47+
// pinnable by commit SHA — skip them.
48+
if (ref.startsWith('./') || ref.startsWith('docker://')) return;
49+
50+
// Test the extracted ref value (not the raw line) to handle quoted forms
51+
// like uses: 'org/repo@<sha>' where a closing quote follows the SHA.
52+
if (!PIN_RE.test(ref)) {
53+
process.stderr.write(
54+
`${filePath}:${idx + 1}: not pinned to 40-char SHA: ${line.trim()}\n`,
55+
);
56+
failed++;
57+
}
58+
});
59+
}
60+
} catch (err) {
61+
process.stderr.write(`lint-workflows: ${err.message}\n`);
62+
process.exit(2);
63+
}
64+
65+
process.exit(failed > 0 ? 1 : 0);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name: Bad Pin Fixture
2+
3+
on: [push]
4+
5+
jobs:
6+
test:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v4
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name: Good Pin Fixture
2+
3+
on: [push]
4+
5+
jobs:
6+
test:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@1234567890abcdef1234567890abcdef12345678 # v4.1.7
10+
- uses: actions/setup-node@1234567890abcdef1234567890abcdef12345678 # v4.0.0
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name: Local Action Fixture
2+
3+
on: [push]
4+
5+
jobs:
6+
test:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: ./.github/actions/my-local-action

0 commit comments

Comments
 (0)