From d4f281e8cac8e2e4a42ccae1a57c989e9423296d Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Thu, 18 Dec 2025 15:50:51 -0600 Subject: [PATCH 1/2] ci: add token pool integration for rate limit distribution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create .github/actions/fetch-token composite action to fetch tokens from mise-versions - Integrate token pool into coverage jobs in test.yml (8 parallel tranches) - Integrate token pool into test-tool jobs in registry.yml (8 parallel tranches) - Each parallel job gets a different token via round-robin from the pool - Falls back to existing GITHUB_TOKEN if pool is unavailable - Tokens are masked in logs with ::add-mask:: Requires MISE_VERSIONS_API_SECRET secret to be configured. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .github/actions/fetch-token/action.yml | 31 ++++++++++++++++++++++++++ .github/workflows/registry.yml | 8 +++++++ .github/workflows/test.yml | 8 +++++++ 3 files changed, 47 insertions(+) create mode 100644 .github/actions/fetch-token/action.yml diff --git a/.github/actions/fetch-token/action.yml b/.github/actions/fetch-token/action.yml new file mode 100644 index 0000000000..d377288d0c --- /dev/null +++ b/.github/actions/fetch-token/action.yml @@ -0,0 +1,31 @@ +name: "Fetch GitHub Token from Pool" +description: "Fetches a token from mise-versions token pool" +inputs: + api-secret: + description: "API secret for mise-versions" + required: true +outputs: + token: + description: "The GitHub token" + value: ${{ steps.fetch.outputs.token }} + token-id: + description: "Token ID for rate-limit reporting" + value: ${{ steps.fetch.outputs.token_id }} +runs: + using: "composite" + steps: + - id: fetch + shell: bash + run: | + if [ -z "${{ inputs.api-secret }}" ]; then + echo "No API secret provided, skipping token fetch" + exit 0 + fi + response=$(curl -sf -H "Authorization: Bearer ${{ inputs.api-secret }}" \ + "https://mise-versions.jdx.dev/api/token" || true) + if [ -n "$response" ]; then + token=$(echo "$response" | jq -r '.token') + echo "::add-mask::$token" + echo "token=$token" >> "$GITHUB_OUTPUT" + echo "token_id=$(echo "$response" | jq -r '.token_id')" >> "$GITHUB_OUTPUT" + fi diff --git a/.github/workflows/registry.yml b/.github/workflows/registry.yml index 8b24db206c..08681253bd 100644 --- a/.github/workflows/registry.yml +++ b/.github/workflows/registry.yml @@ -94,6 +94,14 @@ jobs: tranche: ${{ fromJson(needs.list-changed-tools.outputs.tools == '' && '[0,1,2,3,4,5,6,7]' || '[0]') }} steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - name: Fetch token from pool + id: token + uses: ./.github/actions/fetch-token + with: + api-secret: ${{ secrets.MISE_VERSIONS_API_SECRET }} + - name: Set GITHUB_TOKEN from pool + if: steps.token.outputs.token + run: echo "GITHUB_TOKEN=${{ steps.token.outputs.token }}" >> "$GITHUB_ENV" - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: name: mise diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ee4973265f..248486b7d6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -185,6 +185,14 @@ jobs: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 + - name: Fetch token from pool + id: token + uses: ./.github/actions/fetch-token + with: + api-secret: ${{ secrets.MISE_VERSIONS_API_SECRET }} + - name: Set GITHUB_TOKEN from pool + if: steps.token.outputs.token + run: echo "GITHUB_TOKEN=${{ steps.token.outputs.token }}" >> "$GITHUB_ENV" - name: Install build and test dependencies run: | sudo apt-get update From a608195f971a34936bd08345ab401d46768ffb9c Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Thu, 18 Dec 2025 15:57:56 -0600 Subject: [PATCH 2/2] fix(ci): validate token format before setting GITHUB_TOKEN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the API returns valid JSON but the token field is missing or null, jq outputs the literal string "null". Add validation to ensure the token matches GitHub token format (gh*_...) before outputting it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .github/actions/fetch-token/action.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/actions/fetch-token/action.yml b/.github/actions/fetch-token/action.yml index d377288d0c..4141616641 100644 --- a/.github/actions/fetch-token/action.yml +++ b/.github/actions/fetch-token/action.yml @@ -25,7 +25,12 @@ runs: "https://mise-versions.jdx.dev/api/token" || true) if [ -n "$response" ]; then token=$(echo "$response" | jq -r '.token') - echo "::add-mask::$token" - echo "token=$token" >> "$GITHUB_OUTPUT" - echo "token_id=$(echo "$response" | jq -r '.token_id')" >> "$GITHUB_OUTPUT" + # Validate token looks like a GitHub token (starts with gh and has reasonable length) + if [[ "$token" =~ ^gh[a-z]_[A-Za-z0-9_]+$ ]] && [ ${#token} -ge 20 ]; then + echo "::add-mask::$token" + echo "token=$token" >> "$GITHUB_OUTPUT" + echo "token_id=$(echo "$response" | jq -r '.token_id')" >> "$GITHUB_OUTPUT" + else + echo "Invalid or missing token in response, skipping" + fi fi