Skip to content

Commit eef46b1

Browse files
committed
Fix GitHub Actions workflow linter findings
Address actionlint, octoscan, poutine and zizmor findings: drop persisted checkout credentials, add explicit permissions and concurrency, install actionlint from a checksummed release, avoid template injection, and document intentional exceptions.
1 parent f5fc979 commit eef46b1

10 files changed

Lines changed: 103 additions & 9 deletions

File tree

‎.github/poutine.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
skip:
2+
# Every third-party action is pinned to a full commit SHA, which is what protects against
3+
# a compromised upstream; whether the publisher is a "verified creator" adds nothing on top.
4+
- rule: github_action_from_unverified_creator_used

‎.github/workflows/build.yml‎

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ concurrency:
1212
group: build-${{ github.head_ref || github.run_id }} # will be canceled on subsequent pushes in pull requests but not branches
1313
cancel-in-progress: true
1414

15+
permissions:
16+
contents: read
17+
1518
jobs:
1619
lint:
1720
name: "Lint"
@@ -37,6 +40,8 @@ jobs:
3740

3841
- name: "Checkout"
3942
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
43+
with:
44+
persist-credentials: false
4045

4146
- name: "Install PHP"
4247
uses: "shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962" # v2
@@ -66,10 +71,13 @@ jobs:
6671

6772
- name: "Checkout"
6873
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
74+
with:
75+
persist-credentials: false
6976

7077
- name: "Checkout build-cs"
7178
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
7279
with:
80+
persist-credentials: false
7381
repository: "phpstan/build-cs"
7482
path: "build-cs"
7583
ref: "2.x"
@@ -148,6 +156,8 @@ jobs:
148156

149157
- name: "Checkout"
150158
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
159+
with:
160+
persist-credentials: false
151161

152162
- name: "Install PHP"
153163
uses: "shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962" # v2
@@ -156,7 +166,9 @@ jobs:
156166
php-version: "${{ matrix.php-version }}"
157167

158168
- name: "Require specific PHPUnit version"
159-
run: "composer require --dev phpunit/phpunit:${{ matrix.phpunit-version }}"
169+
env:
170+
PHPUNIT_VERSION: ${{ matrix.phpunit-version }}
171+
run: composer require --dev "phpunit/phpunit:$PHPUNIT_VERSION"
160172

161173
- name: "Install lowest dependencies"
162174
if: ${{ matrix.dependencies == 'lowest' }}
@@ -221,6 +233,8 @@ jobs:
221233

222234
- name: "Checkout"
223235
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
236+
with:
237+
persist-credentials: false
224238

225239
- name: "Install PHP"
226240
uses: "shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962" # v2
@@ -231,7 +245,9 @@ jobs:
231245
tools: composer:v2
232246

233247
- name: "Require specific PHPUnit version"
234-
run: "composer require --dev phpunit/phpunit:${{ matrix.phpunit-version }}"
248+
env:
249+
PHPUNIT_VERSION: ${{ matrix.phpunit-version }}
250+
run: composer require --dev "phpunit/phpunit:$PHPUNIT_VERSION"
235251

236252
- name: "Install lowest dependencies"
237253
if: ${{ matrix.dependencies == 'lowest' }}
@@ -266,15 +282,19 @@ jobs:
266282

267283
- name: "Checkout"
268284
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
285+
with:
286+
persist-credentials: false
269287

270288
- name: "Checkout build-infection"
271289
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
272290
with:
291+
persist-credentials: false
273292
repository: "phpstan/build-infection"
274293
path: "build-infection"
275294
ref: "1.x"
276295

277-
- uses: ./build-infection/.github/actions/setup-php
296+
# The action comes from the phpstan/build-infection checkout above, which the $/ self-repository syntax cannot load
297+
- uses: ./build-infection/.github/actions/setup-php # zizmor: ignore[self-repository]
278298
with:
279299
php-version: "${{ matrix.php-version }}"
280300
php-extensions: mbstring
@@ -334,14 +354,16 @@ jobs:
334354

335355
- name: "Checkout"
336356
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
357+
with:
358+
persist-credentials: false
337359

338360
- name: "Install PHP"
339361
uses: "shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962" # v2
340362
with:
341363
coverage: "none"
342364
php-version: "8.5"
343365

344-
- uses: "ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda" # v4.0.0
366+
- uses: "ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda" # 4.0.0
345367

346368
- name: "Name Collision Detector"
347369
run: "make name-collision"

‎.github/workflows/create-tag.yml‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ on:
1515
- patch
1616
- minor
1717

18+
concurrency:
19+
group: create-tag
20+
cancel-in-progress: true
21+
22+
permissions:
23+
contents: read
24+
1825
jobs:
1926
create-tag:
2027
name: "Create tag"
@@ -25,7 +32,8 @@ jobs:
2532
with:
2633
egress-policy: audit
2734

28-
- name: "Checkout"
35+
# Credentials must stay persisted: rickstaa/action-create-tag pushes the tag with them
36+
- name: "Checkout" # zizmor: ignore[artipacked]
2937
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
3038
with:
3139
fetch-depth: 0

‎.github/workflows/e2e-tests.yml‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,21 @@ jobs:
4141

4242
- name: "Checkout"
4343
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
44+
with:
45+
persist-credentials: false
4446

4547
- name: "Install PHP"
4648
uses: "shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962" # 2.40.0
4749
with:
4850
coverage: "none"
4951
php-version: "8.3"
5052

51-
- uses: "ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda" # v4.0.0
53+
- uses: "ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda" # 4.0.0
5254

5355
- name: "Install bashunit"
5456
uses: "TypedDevs/bashunit@8d4f357f52df7596f92ece2d6c049d91d45517a2" # 0.52.0
5557
with:
5658
directory: "e2e"
5759

5860
- name: "Test"
59-
run: ${{ matrix.script }}
61+
run: ${{ matrix.script }} # zizmor: ignore[template-injection] the script is defined by the matrix above

‎.github/workflows/lint-workflows.yml‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,15 @@ on:
88
branches:
99
- "2.1.x"
1010

11+
concurrency:
12+
group: lint-workflows-${{ github.head_ref || github.run_id }} # will be canceled on subsequent pushes in pull requests but not branches
13+
cancel-in-progress: true
14+
1115
permissions: {}
1216

1317
jobs:
1418
actionlint:
19+
name: actionlint
1520
runs-on: ubuntu-latest
1621
steps:
1722
- name: Harden the runner (Audit all outbound calls)
@@ -20,10 +25,18 @@ jobs:
2025
egress-policy: audit
2126

2227
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
28+
with:
29+
persist-credentials: false
30+
2331
- name: Check workflow files
32+
env:
33+
ACTIONLINT_VERSION: "1.7.12"
34+
ACTIONLINT_SHA256: "8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8"
2435
run: |
2536
echo "::add-matcher::.github/actionlint-matcher.json"
26-
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
37+
curl -fsSL -o actionlint.tar.gz "https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz"
38+
echo "${ACTIONLINT_SHA256} actionlint.tar.gz" | sha256sum -c -
39+
tar -xzf actionlint.tar.gz actionlint
2740
./actionlint -color
2841
shell: bash
2942

@@ -40,11 +53,17 @@ jobs:
4053
egress-policy: audit
4154

4255
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
56+
with:
57+
persist-credentials: false
58+
4359
- name: Run octoscan
4460
id: octoscan
4561
uses: synacktiv/action-octoscan@6b1cf2343893dfb9e5f75652388bd2dc83f456b0 # v1.0.0
4662
with:
4763
filter_triggers: ''
64+
# The only custom-ref checkouts are phpstan/build-cs and phpstan/build-infection at fixed branches,
65+
# and the only local action comes from the phpstan/build-infection checkout.
66+
ignore: "Use of 'actions/checkout' with a custom ref|Use of local action .\\./build-infection/"
4867

4968
- name: Upload SARIF file to GitHub
5069
uses: github/codeql-action/upload-sarif@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1

‎.github/workflows/lock-closed-issues.yml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,16 @@ on:
44
schedule:
55
- cron: '7 0 * * *'
66

7+
concurrency:
8+
group: lock-closed-issues
9+
cancel-in-progress: true
10+
711
permissions:
812
contents: read
913

1014
jobs:
1115
lock:
16+
name: "Lock closed issues"
1217
permissions:
1318
issues: write # for dessant/lock-threads to lock issues
1419
runs-on: ubuntu-latest

‎.github/workflows/release-toot.yml‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,15 @@ on:
66
release:
77
types: [published]
88

9+
concurrency:
10+
group: toot-${{ github.event.release.tag_name }}
11+
cancel-in-progress: true
12+
13+
permissions: {}
14+
915
jobs:
1016
toot:
17+
name: "Toot release"
1118
runs-on: ubuntu-latest
1219
steps:
1320
- name: Harden the runner (Audit all outbound calls)

‎.github/workflows/release-tweet.yml‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,15 @@ on:
66
release:
77
types: [published]
88

9+
concurrency:
10+
group: tweet-${{ github.event.release.tag_name }}
11+
cancel-in-progress: true
12+
13+
permissions: {}
14+
915
jobs:
1016
tweet:
17+
name: "Tweet release"
1118
runs-on: ubuntu-latest
1219
steps:
1320
- name: Harden the runner (Audit all outbound calls)

‎.github/workflows/release.yml‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ on:
77
tags:
88
- '*'
99

10+
concurrency:
11+
group: release-${{ github.ref }}
12+
cancel-in-progress: true
13+
14+
permissions:
15+
contents: read
16+
1017
jobs:
1118
deploy:
1219
name: "Deploy"
@@ -20,14 +27,16 @@ jobs:
2027

2128
- name: "Checkout"
2229
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
30+
with:
31+
persist-credentials: false
2332

2433
- name: Generate changelog
2534
id: changelog
2635
uses: metcalfc/changelog-generator@bb7a08e07e326061351dab6ce89c72f13797043c # v4.9.1
2736
with:
2837
myToken: ${{ secrets.PHPSTAN_BOT_TOKEN }}
2938

30-
- name: "Create release"
39+
- name: "Create release" # zizmor: ignore[superfluous-actions]
3140
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
3241
with:
3342
token: ${{ secrets.PHPSTAN_BOT_TOKEN }}

‎.github/zizmor.yml‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
rules:
2+
secrets-outside-env:
3+
config:
4+
# Repository-level secrets used by release automation; they are not scoped to deployment environments.
5+
allow:
6+
- PHPSTAN_BOT_TOKEN
7+
- MASTODON_ACCESS_TOKEN
8+
- TWITTER_CONSUMER_API_KEY
9+
- TWITTER_CONSUMER_API_SECRET
10+
- TWITTER_ACCESS_TOKEN
11+
- TWITTER_ACCESS_TOKEN_SECRET

0 commit comments

Comments
 (0)