From cccfef03aa35cbc1ae639b1cc1915839e8a3409d Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Wed, 27 May 2026 12:32:08 -0400 Subject: [PATCH 1/7] Add GitHub Actions audit job to CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Runs actionlint and zizmor on workflow files. Placed after the rubocop lint job since it is a linting concern. 🤖 Assisted by Claude --- .github/workflows/ruby.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index cd09b729..61519f9b 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -54,3 +54,20 @@ jobs: run: bundle install --jobs 4 --retry 3 - name: Run rubocop run: bundle exec rubocop --parallel + + lint-actions: + name: GitHub Actions audit + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + + - name: Run actionlint + uses: rhysd/actionlint@v1.7.11 + + - name: Run zizmor + uses: zizmorcore/zizmor-action@v0.5.2 + with: + advanced-security: false From c35243b00509f81fbee4f6c82e1f749f7b7ddc53 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Wed, 27 May 2026 12:32:21 -0400 Subject: [PATCH 2/7] Configure Dependabot for bundler and github-actions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Batches all github-actions updates into a single weekly PR. Adds cooldown windows to both ecosystems so updates soak before landing; github-actions matches the 7-day pinact --min-age. 🤖 Assisted by Claude --- .github/dependabot.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..2e2b29a7 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,22 @@ +version: 2 +updates: + - package-ecosystem: bundler + directory: "/" + schedule: + interval: weekly + cooldown: + semver-major-days: 7 + semver-minor-days: 3 + semver-patch-days: 2 + default-days: 7 + + - package-ecosystem: github-actions + directory: "/" + groups: + github-actions: + patterns: + - "*" + schedule: + interval: weekly + cooldown: + default-days: 7 From ae5250f7defaff5ec8ceca6696621cbd68306389 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Wed, 27 May 2026 12:33:33 -0400 Subject: [PATCH 3/7] Pin GitHub Actions to SHA hashes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ran `pinact run --min-age 7` to pin all actions to commit SHAs with version comments. Matches the 7-day cooldown in dependabot.yml. 🤖 Assisted by Claude --- .github/workflows/ruby.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 61519f9b..58f2d9cc 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -25,9 +25,9 @@ jobs: rubygems_version: '3.6.9' name: Ruby ${{ matrix.ruby }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 - name: Set up Ruby - uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 with: ruby-version: ${{ matrix.ruby }} - name: Update RubyGems @@ -45,9 +45,9 @@ jobs: rubocop: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 - name: Set up Ruby - uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 with: ruby-version: 2.7 - name: Install dependencies @@ -60,14 +60,14 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Run actionlint - uses: rhysd/actionlint@v1.7.11 + uses: rhysd/actionlint@393031adb9afb225ee52ae2ccd7a5af5525e03e8 # v1.7.11 - name: Run zizmor - uses: zizmorcore/zizmor-action@v0.5.2 + uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2 with: advanced-security: false From 485fa8a43446f2c1f5907cbe6f830c7a58950a79 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Wed, 27 May 2026 12:34:57 -0400 Subject: [PATCH 4/7] Harden workflow permissions and checkout credentials MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves zizmor medium findings: - excessive-permissions: deny-all permissions: {} at workflow level, scope contents: read per job - artipacked: persist-credentials: false on checkout in test/lint jobs (neither pushes to git) 🤖 Assisted by Claude --- .github/workflows/ruby.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 58f2d9cc..52fa5616 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -2,9 +2,13 @@ name: CI on: [ push, pull_request ] +permissions: {} + jobs: tests: runs-on: ubuntu-latest + permissions: + contents: read strategy: fail-fast: false matrix: @@ -26,6 +30,8 @@ jobs: name: Ruby ${{ matrix.ruby }} steps: - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 + with: + persist-credentials: false - name: Set up Ruby uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 with: @@ -44,8 +50,12 @@ jobs: # rubocop linting rubocop: runs-on: ubuntu-latest + permissions: + contents: read steps: - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 + with: + persist-credentials: false - name: Set up Ruby uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 with: @@ -58,6 +68,8 @@ jobs: lint-actions: name: GitHub Actions audit runs-on: ubuntu-latest + permissions: + contents: read steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 From 46f2b224c5b4c28ee0cb85c2545c242e57f9a41d Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Wed, 27 May 2026 12:36:01 -0400 Subject: [PATCH 5/7] Suppress SC2086 on RubyGems update step MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit actionlint/shellcheck flags the unquoted ${RUBYGEMS_VERSION:-}, but the unquoted expansion is intentional: when the version is unset the arg must vanish so `gem update --system` picks the latest. Quoting would pass an empty version string instead. Suppress with a reason. 🤖 Assisted by Claude --- .github/workflows/ruby.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 52fa5616..02104378 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -40,6 +40,7 @@ jobs: env: RUBYGEMS_VERSION: ${{ matrix.rubygems_version }} run: | + # shellcheck disable=SC2086 # empty version is intentional: no arg means update to latest gem update --system ${RUBYGEMS_VERSION:-} gem -v - name: Install dependencies From 277934112529e76f8ec5bf6e19c2bf049984f6ef Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Wed, 27 May 2026 12:50:25 -0400 Subject: [PATCH 6/7] Prevent duplicate action runs on pull requests --- .github/workflows/ruby.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 02104378..116e7138 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -1,6 +1,10 @@ name: CI -on: [ push, pull_request ] +on: + push: + branches: [ master ] + pull_request: + types: [ opened, synchronize ] permissions: {} From 5f276baf3c92eb5fbbbb71f2799c5bf8acffe99c Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Wed, 27 May 2026 13:11:17 -0400 Subject: [PATCH 7/7] Pin actions/checkout consistently Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .github/workflows/ruby.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 116e7138..a275fb01 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -77,7 +77,7 @@ jobs: contents: read steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 with: persist-credentials: false