Compare commits

..
Author SHA1 Message Date
Dylan M. Taylor 07471d404d ci: verify the actions lockfile in CI
Fails the build when .github/workflows/actions.lock stops matching the
workflows, or when a locked pin no longer verifies upstream, so a stale or
tampered lockfile cannot go unnoticed between dependency updates.
2026-11-12 07:22:42 -05:00
Dylan M. Taylor 78401059b6 ci: lock workflow actions through an actions.lock lockfile
Mutable action tags are a supply-chain risk: a moved tag runs different code
without a diff. Every workflow action is now pinned through
.github/workflows/actions.lock, and CI verifies the lockfile so an out-of-sync
or tampered one fails instead of running.

arch-package was pinned to 9d67905, a commit no longer on any branch or tag of
craft-common-actions, so it is back on main like the other craft actions here.

S7637 wants an inline SHA per action and does not read actions.lock, so the
rule is scoped off for workflow files until Sonar reads lockfiles.
2026-11-12 07:22:16 -05:00
6 changed files with 166 additions and 31 deletions
+93
View File
@@ -0,0 +1,93 @@
# This file is machine-generated by `gh actions-lock`.
# Do not edit by hand; run `gh actions-lock` to update.
# Docs: https://gh.io/actions-lockfile
version: 'v0.0.3'
workflows:
'.github/workflows/artcraft-linux-publish.yml':
- 'actions/checkout@v7.0.1'
- 'actions/download-artifact@v8.0.2'
- 'actions/setup-node@v7.1.0'
- 'actions/upload-artifact@v7.0.2'
- 'step-security/dtolnay-rust-toolchain@v1.0.0'
- 'step-security/harden-runner@v2.22.4'
- 'step-security/rust-cache@v2.9.2'
- 'step-security/tauri-action@v1.0.0'
- 'storytold/craft-common-actions@main'
'.github/workflows/artcraft-macos-publish.yml':
- 'actions/checkout@v7.0.1'
- 'actions/setup-node@v7.1.0'
- 'step-security/dtolnay-rust-toolchain@v1.0.0'
- 'step-security/harden-runner@v2.22.4'
- 'step-security/tauri-action@v1.0.0'
'.github/workflows/artcraft-windows-publish.yml':
- 'actions/checkout@v7.0.1'
- 'actions/setup-node@v7.1.0'
- 'step-security/dtolnay-rust-toolchain@v1.0.0'
- 'step-security/harden-runner@v2.22.4'
- 'step-security/tauri-action@v1.0.0'
'.github/workflows/freebsd.yml': []
'.github/workflows/house-rules.yml': []
'.github/workflows/lockfile.yml':
- 'actions/checkout@v7.0.1'
- 'step-security/harden-runner@v2.22.4'
'.github/workflows/packaging-lint.yml': []
'.github/workflows/sonarcloud.yml': []
dependencies:
'actions/cache@caa296126883cff596d87d8935842f9db880ef25':
ref: 'v5.1.0'
commit: 'sha1-caa296126883cff596d87d8935842f9db880ef25'
owner_id: 44036562
repo_id: 215566462
'actions/checkout@v7.0.1':
ref: 'v7.0.1'
commit: 'sha1-3d3c42e5aac5ba805825da76410c181273ba90b1'
owner_id: 44036562
repo_id: 197814629
'actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333':
ref: 'v8.0.2'
commit: 'sha1-9000827ccba6bdab643e8b6fd33ac0654aef8333'
owner_id: 44036562
repo_id: 192626254
'actions/download-artifact@v8.0.2':
ref: 'v8.0.2'
commit: 'sha1-9000827ccba6bdab643e8b6fd33ac0654aef8333'
owner_id: 44036562
repo_id: 192626254
'actions/setup-node@v7.1.0':
ref: 'v7.1.0'
commit: 'sha1-949feb2413d6458794dcd2491c4babbbce0c15c1'
owner_id: 44036562
repo_id: 189476904
'actions/upload-artifact@v7.0.2':
ref: 'v7.0.2'
commit: 'sha1-cf430e030ddbb5b0abf93d22962f4752f3646cd9'
owner_id: 44036562
repo_id: 192625955
'step-security/dtolnay-rust-toolchain@v1.0.0':
ref: 'v1.0.0'
commit: 'sha1-8dd607977d06adf4ed49b190381e74c17a9dd25f'
owner_id: 88700172
repo_id: 1249865941
'step-security/harden-runner@v2.22.4':
ref: 'v2.22.4'
commit: 'sha1-1d88384fd173af6ecb012dfd0264a306b711241a'
owner_id: 88700172
repo_id: 422287306
'step-security/rust-cache@v2.9.2':
ref: 'v2.9.2'
commit: 'sha1-8871c8ba063416da7c32246932ea6ae08700453e'
owner_id: 88700172
repo_id: 822636713
'step-security/tauri-action@v1.0.0':
ref: 'v1.0.0'
commit: 'sha1-dc662d498edbd35ec8ed564b45d44e955444d1bc'
owner_id: 88700172
repo_id: 1283860856
'storytold/craft-common-actions@main':
ref: 'main'
commit: 'sha1-293de72429d3ed5d9fa92aded5e500544c0fa28f'
owner_id: 76897702
repo_id: 1414429108
uses:
- 'actions/cache@caa296126883cff596d87d8935842f9db880ef25'
- 'actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333'
+20 -20
View File
@@ -14,10 +14,10 @@ jobs:
timeout-minutes: 10
steps:
- name: Harden runner
uses: step-security/harden-runner@1d88384fd173af6ecb012dfd0264a306b711241a # v2.22.4
uses: step-security/harden-runner@v2.22.4
with:
egress-policy: audit
- uses: actions/checkout@v7
- uses: actions/checkout@v7.0.1
- uses: storytold/craft-common-actions/actions/install-apt-packages@main
with:
packages: rpm jq binutils zsync
@@ -39,10 +39,10 @@ jobs:
TAURI_APP_PATH: ${{ github.workspace }}/crates/desktop/artcraft
steps:
- name: Harden runner
uses: step-security/harden-runner@1d88384fd173af6ecb012dfd0264a306b711241a # v2.22.4
uses: step-security/harden-runner@v2.22.4
with:
egress-policy: audit
- uses: actions/checkout@v7
- uses: actions/checkout@v7.0.1
- uses: storytold/craft-common-actions/actions/install-apt-packages@main
with:
packages: libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libssl-dev libclang-dev libasound2-dev libxdo-dev libdbus-1-dev build-essential clang file jq perl cmake nasm rpm zsync gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-libav
@@ -71,16 +71,16 @@ jobs:
PKG_CONFIG_LIBDIR_riscv64gc_unknown_linux_gnu=/usr/lib/riscv64-linux-gnu/pkgconfig:/usr/share/pkgconfig
ENV
echo "CMAKE_TOOLCHAIN_FILE_riscv64gc_unknown_linux_gnu=$GITHUB_WORKSPACE/packaging/linux/riscv64.cmake" >> "$GITHUB_ENV"
- uses: actions/setup-node@v7
- uses: actions/setup-node@v7.1.0
with:
node-version: '22'
cache: npm
cache-dependency-path: frontend/package-lock.json
- uses: step-security/dtolnay-rust-toolchain@8dd607977d06adf4ed49b190381e74c17a9dd25f # v1.0.0
- uses: step-security/dtolnay-rust-toolchain@v1.0.0
with:
toolchain: stable
targets: ${{ matrix.target }}
- uses: step-security/rust-cache@8871c8ba063416da7c32246932ea6ae08700453e # v2.9.2
- uses: step-security/rust-cache@v2.9.2
with:
key: tauri-linux-${{ matrix.arch }}
cache-on-failure: true
@@ -88,7 +88,7 @@ jobs:
working-directory: frontend
- run: ./node_modules/.bin/nx run artcraft:build
working-directory: frontend
- uses: step-security/tauri-action@dc662d498edbd35ec8ed564b45d44e955444d1bc # v1.0.0
- uses: step-security/tauri-action@v1.0.0
with:
projectPath: crates/desktop/artcraft
args: --target ${{ matrix.target }} --bundles ${{ matrix.bundles }} --config ${{ github.workspace }}/packaging/linux/tauri.conf.json
@@ -97,7 +97,7 @@ jobs:
ARCH: ${{ matrix.arch }}
TARGET: ${{ matrix.target }}
run: packaging/linux/package.sh "$ARCH" "$TARGET"
- uses: actions/upload-artifact@v7
- uses: actions/upload-artifact@v7.0.2
with:
name: release-linux-${{ matrix.arch }}
path: dist/release/*
@@ -111,11 +111,11 @@ jobs:
arch: [x86_64, aarch64]
steps:
- name: Harden runner
uses: step-security/harden-runner@1d88384fd173af6ecb012dfd0264a306b711241a # v2.22.4
uses: step-security/harden-runner@v2.22.4
with:
egress-policy: audit
- uses: actions/checkout@v7
- uses: actions/download-artifact@v8
- uses: actions/checkout@v7.0.1
- uses: actions/download-artifact@v8.0.2
with:
name: release-linux-${{ matrix.arch }}
path: dist/linux
@@ -128,7 +128,7 @@ jobs:
files=(dist/linux/artcraft-*-linux-"$ARCH".tar.gz)
test "${#files[@]}" -eq 1
echo "path=${files[0]}" >> "$GITHUB_OUTPUT"
- uses: storytold/craft-common-actions/actions/arch-package@9d6790582b4997aa2120f4413cdb55c0b6f77fae # extra-depends support (#161)
- uses: storytold/craft-common-actions/actions/arch-package@main # extra-depends support (#161)
with:
tarball: ${{ steps.tarball.outputs.path }}
arch: ${{ matrix.arch }}
@@ -138,7 +138,7 @@ jobs:
for package in dist/release/*.pkg.tar.zst; do
tar --zstd -xOf "$package" .PKGINFO | grep -Fx 'depend = webkit2gtk-4.1'
done
- uses: actions/upload-artifact@v7
- uses: actions/upload-artifact@v7.0.2
with:
name: release-arch-${{ matrix.arch }}
path: dist/release/*.pkg.tar.zst
@@ -158,11 +158,11 @@ jobs:
- {arch: aarch64, runner: ubuntu-24.04-arm}
steps:
- name: Harden runner
uses: step-security/harden-runner@1d88384fd173af6ecb012dfd0264a306b711241a # v2.22.4
uses: step-security/harden-runner@v2.22.4
with:
egress-policy: audit
- uses: actions/checkout@v7
- uses: actions/download-artifact@v8
- uses: actions/checkout@v7.0.1
- uses: actions/download-artifact@v8.0.2
with:
name: release-linux-${{ matrix.arch }}
path: dist/linux
@@ -180,7 +180,7 @@ jobs:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
run: packaging/linux/flatpak.sh
- uses: actions/upload-artifact@v7
- uses: actions/upload-artifact@v7.0.2
with:
name: release-flatpak-${{ matrix.arch }}
path: |
@@ -194,10 +194,10 @@ jobs:
contents: write
steps:
- name: Harden runner
uses: step-security/harden-runner@1d88384fd173af6ecb012dfd0264a306b711241a # v2.22.4
uses: step-security/harden-runner@v2.22.4
with:
egress-policy: audit
- uses: actions/checkout@v7
- uses: actions/checkout@v7.0.1
- name: Read version
id: version
run: echo "value=$(jq -r .version crates/desktop/artcraft/tauri.conf.json)" >> "$GITHUB_OUTPUT"
+5 -5
View File
@@ -39,18 +39,18 @@ jobs:
timeout-minutes: 60
steps:
- name: Harden runner
uses: step-security/harden-runner@1d88384fd173af6ecb012dfd0264a306b711241a # v2.22.4
uses: step-security/harden-runner@v2.22.4
with:
egress-policy: audit
- uses: actions/checkout@v7
- uses: actions/checkout@v7.0.1
- name: setup node
uses: actions/setup-node@v7
uses: actions/setup-node@v7.1.0
with:
node-version: lts/*
- name: install Rust stable
uses: step-security/dtolnay-rust-toolchain@8dd607977d06adf4ed49b190381e74c17a9dd25f # v1.0.0
uses: step-security/dtolnay-rust-toolchain@v1.0.0
with:
toolchain: stable
targets: ${{ matrix.platform == 'macos-latest-xlarge' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
@@ -230,7 +230,7 @@ jobs:
- name: build and publish
uses: step-security/tauri-action@dc662d498edbd35ec8ed564b45d44e955444d1bc # v1.0.0
uses: step-security/tauri-action@v1.0.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_ID: ${{ secrets.APPLE_ID }}
@@ -34,13 +34,13 @@ jobs:
timeout-minutes: 90
steps:
- name: Harden runner
uses: step-security/harden-runner@1d88384fd173af6ecb012dfd0264a306b711241a # v2.22.4
uses: step-security/harden-runner@v2.22.4
with:
egress-policy: audit
- uses: actions/checkout@v7
- uses: actions/checkout@v7.0.1
- name: install Rust stable
uses: step-security/dtolnay-rust-toolchain@8dd607977d06adf4ed49b190381e74c17a9dd25f # v1.0.0
uses: step-security/dtolnay-rust-toolchain@v1.0.0
with:
toolchain: stable
@@ -54,7 +54,7 @@ jobs:
shell: cmd
- name: setup node
uses: actions/setup-node@v7
uses: actions/setup-node@v7.1.0
with:
node-version: lts/*
@@ -107,7 +107,7 @@ jobs:
$config | ConvertTo-Json -Depth 10 | Set-Content tauri.conf.json
- name: build and publish
uses: step-security/tauri-action@dc662d498edbd35ec8ed564b45d44e955444d1bc # v1.0.0
uses: step-security/tauri-action@v1.0.0
env:
# NB(bt): This is needed by wreq. Hopefully it doesn't kill Tauri
RUSTFLAGS: "-C target-feature=+crt-static"
+34
View File
@@ -0,0 +1,34 @@
name: Lockfile
# Fails when .github/workflows/actions.lock is out of sync with the workflows, or when a locked pin
# no longer verifies upstream, so a moved tag cannot slip a different commit into a run.
# Docs: https://gh.io/actions-lockfile
on:
pull_request:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
env:
GH_TOKEN: ${{ github.token }}
jobs:
lockfile:
name: Lockfile is in sync
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- name: Harden runner
uses: step-security/harden-runner@v2.22.4
with:
egress-policy: audit
- uses: actions/checkout@v7.0.1
with:
persist-credentials: false
- name: Install gh-actions-lock
run: gh extension install github/gh-actions-lock --pin v0.4.1
- name: Verify the lockfile
run: gh actions-lock --verify
+9 -1
View File
@@ -22,10 +22,18 @@ sonar.exclusions=crates/vendor/**,crates/api_clients/grok_consumer_client/src/cr
# test/app/Classes/ApiManager/utils/, which call `it` themselves.
# S2819 (message origin): a dedicated worker's `message` events come only from the page that
# started it; they carry no origin to check.
sonar.issue.ignore.multicriteria=deterministic_rng,api_test_helpers,worker_messages
sonar.issue.ignore.multicriteria=deterministic_rng,api_test_helpers,worker_messages,gha-lockfile
sonar.issue.ignore.multicriteria.deterministic_rng.ruleKey=rust:S4347
sonar.issue.ignore.multicriteria.deterministic_rng.resourceKey=crates/schema/public/tokens/src/deterministic_rng.rs
sonar.issue.ignore.multicriteria.api_test_helpers.ruleKey=typescript:S2187
sonar.issue.ignore.multicriteria.api_test_helpers.resourceKey=frontend/apps/artcraft/test/app/Classes/ApiManager/**
sonar.issue.ignore.multicriteria.worker_messages.ruleKey=typescript:S2819
sonar.issue.ignore.multicriteria.worker_messages.resourceKey=**/*.worker.ts
# githubactions:S7637 asks for every action to be pinned to a commit SHA. A workflow covered by
# .github/workflows/actions.lock runs the commit the lockfile records, so its tag refs are pinned
# and the lockfile covers the actions those actions use too. Sonar does not read lockfiles yet, so
# the rule flags the tag refs anyway:
# https://community.sonarsource.com/t/githubactions-s7637-false-positives-for-actions-pinned-through-native-actions-lock/190814
sonar.issue.ignore.multicriteria.gha-lockfile.ruleKey=githubactions:S7637
sonar.issue.ignore.multicriteria.gha-lockfile.resourceKey=.github/workflows/**