From b4c981aaea5ebfb19af30f76629155126bb0a8f2 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 18 Sep 2025 14:57:46 +0200 Subject: [PATCH 1/2] GH Actions: "pin" all action runners Recently there has been more and more focus on securing GH Actions workflows - in part due to some incidents. The problem with "unpinned" action runners is as follows: * Tags are mutable, which means that a tag could point to a safe commit today, but to a malicious commit tomorrow. Note that GitHub is currently beta-testing a new "immutable releases" feature (= tags and release artifacts can not be changed anymore once the release is published), but whether that has much effect depends on the ecosystem of the packages using the feature. Aside from that, it will likely take years before all projects adopt _immutable releases_. * Action runners often don't even point to a tag, but to a branch, making the used action runner a moving target. _Note: this type of "floating major" for action runners used to be promoted as good practice when the ecosystem was "young". Insights have since changed._ While it is convenient to use "floating majors" of action runners, as this means you only need to update the workflows on a new major release of the action runner, the price is higher risk of malicious code being executed in workflows. Dependabot, by now, can automatically submit PRs to update pinned action runners too, as long as the commit-hash pinned runner is followed by a comment listing the released version the commit is pointing to. So, what with Dependabot being capable of updating workflows with pinned action runners, I believe it is time to update the workflows to the _current_ best practice of using commit-hash pinned action runners. The downside of this change is that there will be more frequent Dependabot PRs. If this would become a burden/irritating, the following mitigations can be implemented: 1. Updating the Dependabot config to group updates instead of sending individual PRs per action runner. 2. A workflow to automatically merge Dependabot PRs as long as CI passes. Ref: https://docs.github.com/en/actions/reference/security/secure-use#using-third-party-actions --- .github/workflows/basic-qa.yml | 16 ++++++++-------- .github/workflows/label-merge-conflicts.yml | 2 +- .github/workflows/label-new-prs.yml | 6 +++--- .github/workflows/label-remove-outdated.yml | 8 ++++---- .github/workflows/pr-comment.yml | 4 ++-- .github/workflows/publish-wiki.yml | 12 ++++++------ 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/.github/workflows/basic-qa.yml b/.github/workflows/basic-qa.yml index c1708b8..2b95f25 100644 --- a/.github/workflows/basic-qa.yml +++ b/.github/workflows/basic-qa.yml @@ -30,17 +30,17 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Restore lychee cache - uses: actions/cache@v4 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 with: path: .lycheecache key: cache-lychee-${{ github.sha }} restore-keys: cache-lychee- - name: Link Checker - uses: lycheeverse/lychee-action@v2 + uses: lycheeverse/lychee-action@885c65f3dc543b57c898c8099f4e08c8afd178a2 # v2.6.1 with: # Sidebar file exclusion is needed to work-around an upstream bug. # Should be removed once bug https://github.com/lycheeverse/lychee/issues/1788 has been fixed. @@ -57,10 +57,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Spellcheck - uses: streetsidesoftware/cspell-action@v7 + uses: streetsidesoftware/cspell-action@dcd03dc3e8a59ec2e360d0c62db517baa0b4bb6d # v7.2.0 with: # Define glob patterns to filter the files to be checked. Use a new line between patterns to define multiple patterns. files: '**/*.md' @@ -80,14 +80,14 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Set up problem matcher - uses: lumaxis/shellcheck-problem-matchers@v2 + uses: lumaxis/shellcheck-problem-matchers@b02a1715a00c729b20eed3ebb7edf56fa9a433ba # v2.1.0 with: format: gcc - name: Run ShellCheck - uses: ludeeus/action-shellcheck@2.0.0 + uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # 2.0.0 with: format: gcc diff --git a/.github/workflows/label-merge-conflicts.yml b/.github/workflows/label-merge-conflicts.yml index 2f26103..1c3eb7a 100644 --- a/.github/workflows/label-merge-conflicts.yml +++ b/.github/workflows/label-merge-conflicts.yml @@ -21,7 +21,7 @@ jobs: steps: - name: Check PRs for merge conflicts - uses: eps1lon/actions-label-merge-conflict@v3 + uses: eps1lon/actions-label-merge-conflict@1df065ebe6e3310545d4f4c4e862e43bdca146f0 # v3.0.3 with: dirtyLabel: "Status: has merge conflict" repoToken: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/label-new-prs.yml b/.github/workflows/label-new-prs.yml index bba8b37..474ea95 100644 --- a/.github/workflows/label-new-prs.yml +++ b/.github/workflows/label-new-prs.yml @@ -25,7 +25,7 @@ jobs: steps: - name: Label new PRs - uses: srvaroa/labeler@v1 + uses: srvaroa/labeler@9c29ad1ef33d169f9ef33c52722faf47a566bcf3 # v1 env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" @@ -38,10 +38,10 @@ jobs: steps: # Checkout is needed to use the `use_local_config` option. - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Verify changes to the labeling logic - uses: srvaroa/labeler@v1 + uses: srvaroa/labeler@9c29ad1ef33d169f9ef33c52722faf47a566bcf3 # v1 with: use_local_config: true fail_on_error: true diff --git a/.github/workflows/label-remove-outdated.yml b/.github/workflows/label-remove-outdated.yml index b40c953..74fe648 100644 --- a/.github/workflows/label-remove-outdated.yml +++ b/.github/workflows/label-remove-outdated.yml @@ -18,7 +18,7 @@ jobs: name: Clean up labels on issue close steps: - - uses: mondeja/remove-labels-gh-action@v2 + - uses: mondeja/remove-labels-gh-action@b7118e4ba5dca74acf1059b3cb7660378ff9ab1a # v2.0.0 with: token: ${{ secrets.GITHUB_TOKEN }} labels: | @@ -35,7 +35,7 @@ jobs: name: "Clean up labels on PR (re-)review request" steps: - - uses: mondeja/remove-labels-gh-action@v2 + - uses: mondeja/remove-labels-gh-action@b7118e4ba5dca74acf1059b3cb7660378ff9ab1a # v2.0.0 with: token: ${{ secrets.GITHUB_TOKEN }} labels: | @@ -48,7 +48,7 @@ jobs: name: Clean up labels on PR merge steps: - - uses: mondeja/remove-labels-gh-action@v2 + - uses: mondeja/remove-labels-gh-action@b7118e4ba5dca74acf1059b3cb7660378ff9ab1a # v2.0.0 with: token: ${{ secrets.GITHUB_TOKEN }} labels: | @@ -68,7 +68,7 @@ jobs: name: Clean up labels on PR close steps: - - uses: mondeja/remove-labels-gh-action@v2 + - uses: mondeja/remove-labels-gh-action@b7118e4ba5dca74acf1059b3cb7660378ff9ab1a # v2.0.0 with: token: ${{ secrets.GITHUB_TOKEN }} labels: | diff --git a/.github/workflows/pr-comment.yml b/.github/workflows/pr-comment.yml index 66c7bbe..06d45f9 100644 --- a/.github/workflows/pr-comment.yml +++ b/.github/workflows/pr-comment.yml @@ -29,7 +29,7 @@ jobs: steps: - name: Download PR info artifact - uses: actions/github-script@v8 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: script: | const allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ @@ -75,7 +75,7 @@ jobs: echo "URL=$value" >> "$GITHUB_OUTPUT" - name: "Post comment to review artifact" - uses: mshick/add-pr-comment@v2 + uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2.8.2 with: issue: ${{ steps.pr_number.outputs.PR_NR }} repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/publish-wiki.yml b/.github/workflows/publish-wiki.yml index 638acb4..e17a8cb 100644 --- a/.github/workflows/publish-wiki.yml +++ b/.github/workflows/publish-wiki.yml @@ -43,10 +43,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Install PHP - uses: shivammathur/setup-php@v2 + uses: shivammathur/setup-php@ec406be512d7077f68eed36e63f4d91bc006edc4 # 2.35.4 with: php-version: 'latest' ini-values: error_reporting=-1, display_errors=On, display_startup_errors=On, log_errors_max_len=0 @@ -119,7 +119,7 @@ jobs: - name: "[PR only] Upload the preprocessed wiki files as an artifact" if: ${{ github.event_name == 'pull_request' }} id: artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: wiki-files path: ./_wiki @@ -132,13 +132,13 @@ jobs: # ################################################################################ - name: Check GitHub Git Operations status - uses: crazy-max/ghaction-github-status@v4 + uses: crazy-max/ghaction-github-status@fa6ac37620bc5d44b93e15caed498629665e9ff5 # v4.2.0 with: git_threshold: partial_outage - name: Deploy to wiki if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }} - uses: Andrew-Chen-Wang/github-wiki-action@v5.0.1 + uses: Andrew-Chen-Wang/github-wiki-action@2c80c13ee98aa43683bd77973ef4916e2eedf817 # v5.0.1 env: COMMIT_MSG: ${{ github.event.head_commit.message }} DEFAULT_COMMIT_MSG: "Update wiki ${{ github.sha }}" @@ -175,7 +175,7 @@ jobs: - name: Upload PR info as artifact if: ${{ github.event_name == 'pull_request' }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: pr_info path: pr/ From aeded16e224a5073c3174bf2a0b245936b30f3bf Mon Sep 17 00:00:00 2001 From: jrfnl Date: Thu, 18 Sep 2025 14:58:10 +0200 Subject: [PATCH 2/2] Dependabot: update config This commit makes two changes to the Dependabot config: 1. It introduces a "cooldown" period for updates to a new major release of action runners. What this means, is that for updates to a new major, the Dependabot will be delayed by 10 days, which should give projects the chance to fix any "teething problems". 2. It introduces a "group". By default Dependabot raises individual PRs for each update. Now, it will group updates to new minor or patch release for all action runners into a single PR. Updates to new major releases of action runners will still be raised as individual PRs. Refs: * https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/optimizing-pr-creation-version-updates * https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference --- .github/dependabot.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f25adbb..df6adaa 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -14,3 +14,11 @@ updates: prefix: "GH Actions:" labels: - "Type: chores/QA/automation" + cooldown: + semver-major-days: 10 + groups: + action-runners: + applies-to: version-updates + update-types: + - "minor" + - "patch"