security: pin all GitHub Actions to commit SHAs (CVE-2025-30066 mitigation)

Pin all GitHub Actions to immutable commit SHAs to prevent supply chain attacks.
This protects against tag-poisoning attacks like the March 2025 tj-actions compromise
that affected 23,000+ repositories.

Changes:
- Pin 55 action references across 19 workflow files to commit SHAs
- Add version comments (e.g., "# v6") for readability
- Manually resolved: gradle/actions, github/codeql-action, actions/setup-node

All actions now use immutable references following GitHub security best practices:
https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions

Future updates should be managed via Dependabot to automate SHA updates.
This commit is contained in:
Johannes Millan 2026-01-21 12:36:30 +01:00
parent aa7103d4a8
commit 9b2afbe109
19 changed files with 57 additions and 57 deletions

View file

@ -13,7 +13,7 @@ jobs:
steps:
- name: Promote Internal Release to Production
uses: kevin-david/promote-play-release@v1.2.0
uses: kevin-david/promote-play-release@d1ed59ca4fd7456b9d8cae062a3684e93b412425 # v1.2.0
with:
service-account-json-raw: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}
package-name: com.superproductivity.superproductivity

View file

@ -18,21 +18,21 @@ jobs:
UNSPLASH_CLIENT_ID: ${{ secrets.UNSPLASH_CLIENT_ID }}
steps:
- name: Checkout sources
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
- uses: actions/setup-node@v6
with:
node-version: 20
- name: Setup Java
uses: actions/setup-java@v5
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5
with:
distribution: 'temurin'
java-version: 21
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5
uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5
# - name: Build with Gradle
# run: ./gradlew build
- name: Setup android-sdk
uses: android-actions/setup-android@v3
uses: android-actions/setup-android@9fc6c4e9069bf8d3d10b2204b1fb8f6ef7065407 # v3
with:
accept-android-sdk-licenses: true
log-accepted-android-sdk-licenses: true #make accepting the android sdk license verbose
@ -77,7 +77,7 @@ jobs:
# APK is now signed automatically by Gradle using signingConfig
- name: 'Upload APK files'
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: sup-android-release
path: android/app/build/outputs/apk/**/*.apk
@ -117,7 +117,7 @@ jobs:
- name: Upload to Google Play Console
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-')
uses: r0adkll/upload-google-play@v1.1.3
uses: r0adkll/upload-google-play@935ef9c68bb393a8e6116b1575626a7f5be3a7fb # v1.1.3
with:
serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}
packageName: com.superproductivity.superproductivity

View file

@ -24,12 +24,12 @@ jobs:
node-version: 20
# required because setting via env.TZ does not work on windows
- name: Set timezone to Europe Standard Time
uses: szenius/set-timezone@v2.0
uses: szenius/set-timezone@1f9716b0f7120e344f0c62bb7b1ee98819aefd42 # v2.0
with:
timezoneWindows: 'W. Europe Standard Time'
- name: Check out Git repository
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
# work around for npm installs from git+https://github.com/johannesjo/J2M.git
@ -75,14 +75,14 @@ jobs:
run: npm run build
- name: Build/Release Electron app
uses: johannesjo/action-electron-builder@v1
uses: johannesjo/action-electron-builder@9ea9e2d991c97668843d57337848e3e2b1ffab3d # v1
with:
build_script_name: empty
release: false
github_token: ${{ secrets.github_token }}
- name: 'Upload Artifact'
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: WinStoreRelease
path: .tmp/app-builds/*.appx

View file

@ -21,7 +21,7 @@ jobs:
node-version: 20
- name: Check out Git repository
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
@ -203,7 +203,7 @@ jobs:
run: ls -la "$RUNNER_TEMP/ipa-output"
- name: Upload IPA artifact
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: sup-ios-release
path: ${{ runner.temp }}/ipa-output/*.ipa

View file

@ -18,7 +18,7 @@ jobs:
- run: sed "s/PACKAGE_VERSION/${package_version}/g" build/linux/PKGBUILD_template > build/linux/PKGBUILD
- name: Publish AUR package
uses: KSXGitHub/github-actions-deploy-aur@v4.1.1
uses: KSXGitHub/github-actions-deploy-aur@2ac5a4c1d7035885d46b10e3193393be8460b6f1 # v4.1.1
with:
pkgname: superproductivity-bin
pkgbuild: build/linux/PKGBUILD

View file

@ -19,7 +19,7 @@ jobs:
with:
node-version: 20
- name: Check out Git repository
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
# work around for npm installs from git+https://github.com/johannesjo/J2M.git

View file

@ -15,7 +15,7 @@ jobs:
steps:
- name: Install Snapcraft
uses: samuelmeuli/action-snapcraft@v3
uses: samuelmeuli/action-snapcraft@fceeb3c308e76f3487e72ef608618de625fb7fe8 # v3
- run: yes | snapcraft promote superproductivity --from-channel latest/edge --to-channel latest/stable
env: # Workaround for https://github.com/snapcore/snapcraft/issues/4439
SNAPCRAFT_HAS_TTY: 'true'

View file

@ -18,7 +18,7 @@ jobs:
with:
node-version: 20
- name: Check out Git repository
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
# work around for npm installs from git+https://github.com/johannesjo/J2M.git
@ -28,7 +28,7 @@ jobs:
ssh://git@github.com/
- name: Install Node.js, NPM and Yarn
uses: actions/setup-node@v6
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
with:
node-version: 20
@ -60,7 +60,7 @@ jobs:
run: npm run buildFrontend:prodWeb
- name: Deploy to Web Server
uses: easingthemes/ssh-deploy@v5.0.3
uses: easingthemes/ssh-deploy@01a39e33483634cbd7ac99020c55b72ca7f098fe # v5.0.3
env:
SSH_PRIVATE_KEY: ${{ secrets.WEB_SERVER_SSH_KEY }}
ARGS: '-rltgoDzvO --delete --exclude "news.json"'

View file

@ -21,7 +21,7 @@ jobs:
with:
node-version: 20
- name: Check out Git repository
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
# work around for npm installs from git+https://github.com/johannesjo/J2M.git
@ -64,7 +64,7 @@ jobs:
- name: 'Upload E2E results on failure'
if: ${{ failure() }}
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: e2eResults
path: .tmp/e2e-test-results/**/*.*
@ -74,10 +74,10 @@ jobs:
run: npm run build
- name: Install Snapcraft
uses: samuelmeuli/action-snapcraft@v3
uses: samuelmeuli/action-snapcraft@fceeb3c308e76f3487e72ef608618de625fb7fe8 # v3
- name: Build/Release Electron app
uses: johannesjo/action-electron-builder@v1
uses: johannesjo/action-electron-builder@9ea9e2d991c97668843d57337848e3e2b1ffab3d # v1
with:
build_script_name: empty
github_token: ${{ secrets.github_token }}
@ -88,7 +88,7 @@ jobs:
# Release to edge if no tag and to candidate if tag
- #otherwise it would be executed twice
if: false == startsWith(github.ref, 'refs/tags/v')
uses: nick-fields/retry@v3
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3
with:
max_attempts: 2
timeout_minutes: 11
@ -115,7 +115,7 @@ jobs:
IS_RELEASE: ${{ startsWith(github.ref, 'refs/tags/v') }}
- name: Check out Git repository
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
# work around for npm installs from git+https://github.com/johannesjo/J2M.git
@ -177,7 +177,7 @@ jobs:
run: npm run build
- name: Build/Release Electron app
uses: johannesjo/action-electron-builder@v1
uses: johannesjo/action-electron-builder@9ea9e2d991c97668843d57337848e3e2b1ffab3d # v1
with:
build_script_name: empty
github_token: ${{ secrets.github_token }}
@ -205,12 +205,12 @@ jobs:
node-version: 20
# required because setting via env.TZ does not work on windows
- name: Set timezone to Europe Standard Time
uses: szenius/set-timezone@v2.0
uses: szenius/set-timezone@1f9716b0f7120e344f0c62bb7b1ee98819aefd42 # v2.0
with:
timezoneWindows: 'W. Europe Standard Time'
- name: Check out Git repository
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
# work around for npm installs from git+https://github.com/johannesjo/J2M.git
@ -240,7 +240,7 @@ jobs:
- name: Setup Chrome
id: setup-chrome
uses: browser-actions/setup-chrome@v2
uses: browser-actions/setup-chrome@b94431e051d1c52dcbe9a7092a4f10f827795416 # v2
- name: Export Chrome path for Karma
shell: pwsh
@ -258,7 +258,7 @@ jobs:
run: npm run build
- name: Build/Release Electron app
uses: johannesjo/action-electron-builder@v1
uses: johannesjo/action-electron-builder@9ea9e2d991c97668843d57337848e3e2b1ffab3d # v1
with:
build_script_name: empty
github_token: ${{ secrets.github_token }}

View file

@ -35,13 +35,13 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 1
- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@v1
uses: anthropics/claude-code-action@a017b830c03e23789b11fb69ed571ea61c12e45c # v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
github_token: ${{ secrets.GITHUB_TOKEN }}

View file

@ -26,13 +26,13 @@ jobs:
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 1
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
uses: anthropics/claude-code-action@a017b830c03e23789b11fb69ed571ea61c12e45c # v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
github_token: ${{ secrets.GITHUB_TOKEN }}

View file

@ -34,7 +34,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
# We must fetch at least the immediate parents so that if this is
@ -53,7 +53,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@4bdb89f48054571735e3792627da6195c57459e2 # v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@ -64,7 +64,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v3
uses: github/codeql-action/autobuild@4bdb89f48054571735e3792627da6195c57459e2 # v3
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@ -78,4 +78,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@4bdb89f48054571735e3792627da6195c57459e2 # v3

View file

@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: 'Checkout Repository'
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
# work around for npm installs from git+https://github.com/johannesjo/J2M.git
@ -25,4 +25,4 @@ jobs:
ssh://git@github.com/
- name: 'Dependency Review'
uses: actions/dependency-review-action@v4
uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4

View file

@ -32,7 +32,7 @@ jobs:
node-version: 20
- name: Check out Git repository
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
@ -101,7 +101,7 @@ jobs:
- name: Upload E2E Results on Failure
if: ${{ failure() }}
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: e2e-results-${{ github.run_id }}
path: .tmp/e2e-test-results/**/*.*

View file

@ -43,7 +43,7 @@ jobs:
run: rm -f dist/browser/ngsw.json dist/browser/ngsw-worker.js dist/browser/safety-worker.js dist/browser/worker-basic.min.js
- name: Run Lighthouse CI
uses: treosh/lighthouse-ci-action@v12
uses: treosh/lighthouse-ci-action@fcd65974f7c4c2bf0ee9d09b84d2489183c29726 # v12
with:
# Configure Lighthouse CI
configPath: './tools/lighthouse/.lighthouserc.json'

View file

@ -9,11 +9,11 @@ jobs:
test-on-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v6
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
with:
node-version: 20
- name: Check out Git repository
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
# work around for npm installs from git+https://github.com/johannesjo/J2M.git
@ -51,7 +51,7 @@ jobs:
run: npm run e2e
- name: 'Upload E2E results on failure'
if: ${{ failure() }}
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: e2eResults
path: .tmp/e2e-test-results/**/*.*

View file

@ -23,7 +23,7 @@ jobs:
node-version: 20
# required because setting via env.TZ does not work on windows
- name: Check out Git repository
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
# work around for npm installs from git+https://github.com/johannesjo/J2M.git
@ -54,14 +54,14 @@ jobs:
run: npm run buildAllElectron:noTests:prod
- name: Build Electron app
uses: johannesjo/action-electron-builder@v1
uses: johannesjo/action-electron-builder@9ea9e2d991c97668843d57337848e3e2b1ffab3d # v1
with:
build_script_name: empty
github_token: ${{ secrets.github_token }}
release: false
- name: 'Upload Artifact'
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: WinBuildStuff
path: .tmp/app-builds/*.exe
@ -82,7 +82,7 @@ jobs:
IS_RELEASE: ${{ startsWith(github.ref, 'refs/tags/v') }}
- name: Check out Git repository
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
# work around for npm installs from git+https://github.com/johannesjo/J2M.git
@ -142,7 +142,7 @@ jobs:
run: npm run build
- name: Build/Release Electron app
uses: johannesjo/action-electron-builder@v1
uses: johannesjo/action-electron-builder@9ea9e2d991c97668843d57337848e3e2b1ffab3d # v1
with:
build_script_name: empty
github_token: ${{ secrets.github_token }}
@ -161,7 +161,7 @@ jobs:
# if: always()
# run: ls -la && cat notarization-error.log
- name: 'Upload Artifact'
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: dmg
path: .tmp/app-builds/*.dmg

View file

@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v6
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
with:
persist-credentials: false
# work around for npm installs from git+https://github.com/johannesjo/J2M.git
@ -23,7 +23,7 @@ jobs:
ssh://git@github.com/
- name: Log in to Docker Hub
uses: docker/login-action@v2
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
@ -38,10 +38,10 @@ jobs:
images: johannesjo/super-productivity
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- name: Build and push Docker image
uses: docker/build-push-action@v6
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6
with:
context: .
push: true

View file

@ -118,7 +118,7 @@ jobs:
fi
- name: Upload DMG artifact
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: mac-dmg-build
path: .tmp/app-builds/*.dmg