From 85a97ee14b6ff1a924dcca6fff32099b6cd71392 Mon Sep 17 00:00:00 2001 From: Dario Curreri Date: Mon, 25 Nov 2024 18:53:12 +1100 Subject: [PATCH] fix: from `PAT` to `id-token` --- README.md | 31 ++--------------------------- action.yml | 58 +++++++++++++++++++++++++++++++++++------------------- 2 files changed, 40 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 2206a74..8e60617 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ I created `checkout-called` to simplify checking out the called repository in yo ## Usage +> This action requires `id-token: write` permissions + To use this action in your called workflows and check out the repository automatically, add the following lines: ```yml @@ -22,32 +24,3 @@ This action mirrors the arguments of [`actions/checkout`](https://github.com/act For example, if you call: `user/repository/.github/workflows/workflow.yml@branch`, it will checkout the `user/repository` repository using `branch` as reference > This repository is committed to maintaining compatibility and same version as [`actions/checkout`](https://github.com/actions/checkout) - -###  Private repository - -According to the GitHub API [documentation](https://docs.github.com/en/rest/actions/workflow-runs?apiVersion=2022-11-28#get-a-workflow-run), -for private repositories, you need to provide a token with `Actions: read` permissions. -To do this, pass the token as an argument: - -```yml -- name: Checkout called repo - uses: dariocurr/checkout-called@main - with: - token: ${{ secrets.TOKEN }} - ``` - -### Nested workflows - -When working with nested reusable workflows (as desribed in issue [#5](https://github.com/dariocurr/checkout-called/issues/5)), the GitHub API for workflow runs does not guarantee the order of the `referenced_workflows`. -This means we cannot rely on `referenced_workflows[0]` being the correct workflow to use. - -Thus, in order to ensure the correctness of the execution, add the `workflow` argument: - -```yml -- name: Checkout called repo - uses: dariocurr/checkout-called@main - with: - workflow: organization/repository/.github/workflows/workflow.yml - ``` - -> The `workflow` argument is used to perform a substring search. A full workflow reference like `organization/repository/.github/workflows/workflow.yml` should be used to avoid conflicts when multiple workflows have the same name diff --git a/action.yml b/action.yml index b1395d3..c746261 100644 --- a/action.yml +++ b/action.yml @@ -112,26 +112,44 @@ runs: id: called_repo shell: bash run: | - # retrieve workflow run metadata calling API - content=$(curl -L -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${{ inputs.token }}" -H "X-GitHub-Api-Version: 2022-11-28" ${{ github.api_url }}/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}) - if [[ -z "${{ inputs.workflow }}" ]]; then - # if no workflow is specified, use the first referenced workflow - data=$(echo $content | jq -r '.referenced_workflows[0]') - else - # if a workflow is specified, filter the referenced workflows - data=$(echo $content | jq --arg path "${{ inputs.workflow }}" '[.referenced_workflows[] | select(.path | contains($path))] | first') - fi - if [ -z "$data" ]; then - # if no referenced workflows are found, exit with an error - echo "::error ::Unable to retrieve the workflow metadata. Please ensure that the given token has the required permissions" - exit 1 - else - # extract the ref and repository from the referenced workflow - ref=$(echo $data | jq -r '.sha') - repository=$(echo $data | jq -r '.path' | cut -d'/' -f1-2) - echo "repository=$repository" >> $GITHUB_OUTPUT - echo "ref=$ref" >> $GITHUB_OUTPUT - fi + JWT=$(curl -s -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL") + PAYLOAD=$(echo "$JWT" | cut -d '.' -f 2 | base64 -d 2>/dev/null || true) + WORKFLOW_REF_LINE==$(echo "$PAYLOAD" | grep -o '"job_workflow_ref":"[^"]*"') + + WORKFLOW_REPOSITORY=$( + echo "$WORKFLOW_REF_LINE" \ + | cut -d':' -f2 \ + | cut -d'@' -f1 \ + | tr -d '"' \ + | cut -d'/' -f1,2 + ) + + WORKFLOW_FULL_REF=$( + echo "$WORKFLOW_REF_LINE" \ + | cut -d':' -f2 \ + | cut -d'@' -f2 \ + | tr -d '"' + ) + + case $WORKFLOW_FULL_REF in + refs/heads/*) + WORKFLOW_REF=${WORKFLOW_FULL_REF#refs/heads/} + ;; + refs/tags/*) + WORKFLOW_REF=${WORKFLOW_FULL_REF#refs/tags/} + ;; + refs/pull/*/merge) + # exception: we got triggered by a pull request, the ref is the base branch + WORKFLOW_REF=$GITHUB_HEAD_REF + ;; + esac + + echo "WORKFLOW_FULL_REF=$WORKFLOW_FULL_REF" + echo "WORKFLOW_REPOSITORY=$WORKFLOW_REPOSITORY" + echo "WORKFLOW_REF=$WORKFLOW_REF" + + echo "WORKFLOW_REPOSITORY=$WORKFLOW_REPOSITORY" >> $GITHUB_OUTPUT + echo "WORKFLOW_REF=$WORKFLOW_REF" >> $GITHUB_OUTPUT - name: Checkout workflows repo if: steps.called_repo.outputs.ref && steps.called_repo.outputs.repository