From c3e43a42033a036c981da96a728bf9fd7e635f00 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Mon, 31 Aug 2026 15:23:23 -0700 Subject: [PATCH 1/2] Add self-hosted Renovate to track shellcheck and rubyfmt version pins Dependabot's github-actions ecosystem only tracks 'uses:' references, so it can't see the shellcheck version+checksum baked into a run: step in ci.yml, or the rubyfmt version pinned in support/latest. Adds a weekly self-hosted Renovate job (avoids installing the hosted GitHub App, which would need broader org-level approval) scoped via enabledManagers to two custom regex managers covering just those two pins, so it doesn't duplicate Dependabot's existing coverage of actions/checkout and zizmor-action. Hoists the shellcheck version/checksum into the lint job's env: block (previously duplicated across two run: steps) so there's a single text location for the regex manager to match and bump. Neither custom manager recomputes checksums automatically -- there's no published checksum for Renovate to fetch for either dependency. A version-only bump PR will fail CI with a checksum mismatch, which is the intended safe failure mode; the PR body points at the manual fix (support/sync-versions.sh for rubyfmt, a manual recompute for shellcheck). Verified locally with 'renovate --platform=local --dry-run=full': both custom managers correctly extract exactly one dependency each, resolve against the real GitHub releases API, and report zero pending updates (matching that both pins are already current). --- .github/renovate-config.json | 35 ++++++++++++++++++++++++++++++++++ .github/workflows/ci.yml | 10 +++++++--- .github/workflows/renovate.yml | 29 ++++++++++++++++++++++++++++ README.md | 11 +++++++++++ 4 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 .github/renovate-config.json create mode 100644 .github/workflows/renovate.yml diff --git a/.github/renovate-config.json b/.github/renovate-config.json new file mode 100644 index 0000000..443ebeb --- /dev/null +++ b/.github/renovate-config.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:recommended"], + "onboarding": false, + "requireConfig": "optional", + "enabledManagers": ["custom.regex"], + "schedule": ["before 4am on monday"], + "customManagers": [ + { + "customType": "regex", + "description": "shellcheck version pinned in ci.yml (checksum needs a manual refresh; CI fails loudly if it's stale)", + "managerFilePatterns": [".github/workflows/ci.yml"], + "matchStrings": [ + "# renovate: datasource=(?.*?) depName=(?.*?)\\s+SHELLCHECK_VERSION: (?\\S+)" + ] + }, + { + "customType": "regex", + "description": "rubyfmt version pinned in support/latest (checksums need a manual refresh via support/sync-versions.sh; CI fails loudly if stale)", + "managerFilePatterns": ["support/latest"], + "matchStrings": ["(?\\S+)"], + "datasourceTemplate": "github-releases", + "depNameTemplate": "fables-tales/rubyfmt", + "extractVersionTemplate": "^v(?.*)$" + } + ], + "packageRules": [ + { + "matchDepNames": ["koalaman/shellcheck", "fables-tales/rubyfmt"], + "prBodyNotes": [ + "This bumps a version pin only. The checksum(s) in this file were **not** updated automatically — CI will fail with a checksum mismatch until they're refreshed. For `fables-tales/rubyfmt`, run `support/sync-versions.sh `. For `koalaman/shellcheck`, recompute the sha256 of the new release's `shellcheck-.linux.x86_64.tar.xz` asset and update `SHELLCHECK_SHA256` in `.github/workflows/ci.yml`." + ] + } + ] +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 03e883e..36643fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,10 @@ permissions: {} jobs: lint: runs-on: ubuntu-latest + env: + # renovate: datasource=github-releases depName=koalaman/shellcheck + SHELLCHECK_VERSION: v0.11.0 + SHELLCHECK_SHA256: 8c3be12b05d5c177a04c29e3c78ce89ac86f1595681cab149b65b97c4e227198 steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -20,13 +24,13 @@ jobs: - name: Download shellcheck run: | curl --fail --silent --show-error --location --output /tmp/shellcheck.tar.xz \ - "https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.linux.x86_64.tar.xz" - echo "8c3be12b05d5c177a04c29e3c78ce89ac86f1595681cab149b65b97c4e227198 /tmp/shellcheck.tar.xz" | sha256sum -c - + "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" + echo "${SHELLCHECK_SHA256} /tmp/shellcheck.tar.xz" | sha256sum -c - tar --extract --xz --file /tmp/shellcheck.tar.xz --directory /tmp shell: bash - name: Shellcheck - run: find . -type f -name "*.sh" -print0 | xargs -0 /tmp/shellcheck-v0.11.0/shellcheck + run: find . -type f -name "*.sh" -print0 | xargs -0 "/tmp/shellcheck-${SHELLCHECK_VERSION}/shellcheck" shell: bash - name: Download actionlint diff --git a/.github/workflows/renovate.yml b/.github/workflows/renovate.yml new file mode 100644 index 0000000..daf79c1 --- /dev/null +++ b/.github/workflows/renovate.yml @@ -0,0 +1,29 @@ +name: Renovate + +on: + schedule: + - cron: "0 4 * * 1" + workflow_dispatch: {} + +permissions: {} + +jobs: + renovate: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - name: Checkout repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Self-hosted Renovate + uses: renovatebot/github-action@39b914146caeff8cd512e61c8992f1d5913af85c # v46.2.5 + env: + RENOVATE_PLATFORM: github + RENOVATE_REPOSITORIES: ${{ github.repository }} + with: + configurationFile: .github/renovate-config.json + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 99ac16f..972ae56 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,17 @@ This downloads each platform's release asset, records its checksum in [`support/latest`](support/latest). Pass `--historical` to pin an older release without changing what `latest` resolves to. +A self-hosted [Renovate](https://github.com/rubyatscale/rubyfmt-action/blob/main/.github/workflows/renovate.yml) +job runs weekly and opens a PR bumping [`support/latest`](support/latest) +when a new `rubyfmt` release is available, and similarly for the `shellcheck` +version pinned in [`ci.yml`](.github/workflows/ci.yml). Neither of those PRs +update the corresponding checksum(s) automatically (there's nothing for +Renovate to safely fetch a checksum from), so CI on those PRs fails until the +checksum is refreshed — run `support/sync-versions.sh ` for `rubyfmt`, +or manually recompute and update `SHELLCHECK_SHA256` for `shellcheck`. +Dependabot (see [`dependabot.yml`](.github/dependabot.yml)) separately +handles the rest of this repo's GitHub Actions dependencies. + ## License This project is licensed under the MIT License. See [LICENSE](LICENSE) for From 2d3258d278da14eb7b8933aa8183ad09d03be9d0 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Mon, 31 Aug 2026 15:39:39 -0700 Subject: [PATCH 2/2] Track actionlint's download script via a tagged, Renovate-tracked SHA pin Previously pinned to an arbitrary commit on rhysd/actionlint's main branch, which isn't something Renovate can sensibly track (every push to main would look like an update). Switched to the same SHA+comment convention used for actions/checkout elsewhere in this repo (commit 914e7df @ v1.7.12, the current latest release), and added a third custom regex manager using the github-tags datasource + digest tracking to keep both the SHA and the version comment in sync automatically -- unlike the shellcheck/rubyfmt pins, this needs no manual follow-up, since there's no separate checksum to refresh. Verified the only functional difference between the two script versions is a hardcoded fallback version string (used only if the script's own GitHub API call fails), and confirmed locally with 'renovate --platform=local --dry-run=full' that the new manager correctly extracts the digest+comment and resolves them against the live rhysd/actionlint tags. --- .github/renovate-config.json | 10 ++++++++++ .github/workflows/ci.yml | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/renovate-config.json b/.github/renovate-config.json index 443ebeb..29cd51d 100644 --- a/.github/renovate-config.json +++ b/.github/renovate-config.json @@ -22,6 +22,16 @@ "datasourceTemplate": "github-releases", "depNameTemplate": "fables-tales/rubyfmt", "extractVersionTemplate": "^v(?.*)$" + }, + { + "customType": "regex", + "description": "actionlint download script, SHA-pinned with a version comment in ci.yml (same convention as our uses:@sha # vX.Y.Z action pins)", + "managerFilePatterns": [".github/workflows/ci.yml"], + "matchStrings": [ + "raw\\.githubusercontent\\.com/rhysd/actionlint/(?[a-f0-9]{40})/scripts/download-actionlint\\.bash\"\\) # (?v\\d+\\.\\d+\\.\\d+)" + ], + "datasourceTemplate": "github-tags", + "depNameTemplate": "rhysd/actionlint" } ], "packageRules": [ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 36643fb..1e89ac6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: shell: bash - name: Download actionlint - run: bash <(curl --fail --silent --show-error --location "https://raw.githubusercontent.com/rhysd/actionlint/011a6d15e749bb3f2d771eed9c7aa0e7e3e10ee7/scripts/download-actionlint.bash") + run: bash <(curl --fail --silent --show-error --location "https://raw.githubusercontent.com/rhysd/actionlint/914e7df21a07ef503a81201c76d2b11c789d3fca/scripts/download-actionlint.bash") # v1.7.12 shell: bash - name: actionlint