From dfcfeca43e4ad1597a1a8bacfca40b25ad821f61 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Wed, 6 Nov 2024 14:00:51 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=AA=20Use=20prefetched=20action=20to?= =?UTF-8?q?=20make=20trampoline?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, the action repository was being cloned from the remote twice, unnecessarily. This patch eliminates this step and uses the copy that was checked out on job start. The generated trampoline action is still copied into the allowlisted working directory so it can be referenced by the relative path starting with `./`. It is now output under `./.github/.tmp/.generated-actions/run-pypi-publish-in-docker-container` which mutates the end-user's workspace slightly but uses a path that is unlikely to clash with somebody else's use. Unfortunately, we cannot use randomized paths because the composite action syntax does not allow accessing variables in `uses:`. Fixes #292. --- action.yml | 22 +++++++++++++--------- create-docker-action.py | 20 ++++++++++++++++++-- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/action.yml b/action.yml index 7f6b746..f4dea68 100644 --- a/action.yml +++ b/action.yml @@ -130,24 +130,28 @@ runs: PR_REF: ${{ github.event.pull_request.head.ref }} PR_REPO: ${{ github.event.pull_request.head.repo.full_name }} PR_REPO_ID: ${{ github.event.pull_request.base.repo.id }} - - name: Check out action repo - uses: actions/checkout@v4 - with: - path: action-repo - ref: ${{ steps.set-repo-and-ref.outputs.ref }} - repository: ${{ steps.set-repo-and-ref.outputs.repo }} - name: Create Docker container action run: | # Create Docker container action - python create-docker-action.py + python ${{ github.action_path }}/create-docker-action.py env: REF: ${{ steps.set-repo-and-ref.outputs.ref }} REPO: ${{ steps.set-repo-and-ref.outputs.repo }} REPO_ID: ${{ steps.set-repo-and-ref.outputs.repo-id }} shell: bash - working-directory: action-repo - name: Run Docker container - uses: ./action-repo/.github/actions/run-docker-container + # The generated trampoline action must exist in the allowlisted + # runner-defined working directory so it can be referenced by the + # relative path starting with `./`. + # + # This mutates the end-user's workspace slightly but uses a path + # that is unlikely to clash with somebody else's use. + # + # We cannot use randomized paths because the composite action + # syntax does not allow accessing variables in `uses:`. This + # means that we end up having to hardcode this path both here and + # in `create-docker-action.py`. + uses: ./.github/.tmp/.generated-actions/run-pypi-publish-in-docker-container with: user: ${{ inputs.user }} password: ${{ inputs.password }} diff --git a/create-docker-action.py b/create-docker-action.py index 16aa54c..6829a9f 100644 --- a/create-docker-action.py +++ b/create-docker-action.py @@ -10,10 +10,12 @@ REPO = os.environ['REPO'] REPO_ID = os.environ['REPO_ID'] REPO_ID_GH_ACTION = '178055147' +ACTION_SHELL_CHECKOUT_PATH = pathlib.Path(__file__).parent.resolve() + def set_image(ref: str, repo: str, repo_id: str) -> str: if repo_id == REPO_ID_GH_ACTION: - return '../../../Dockerfile' + return str(ACTION_SHELL_CHECKOUT_PATH / 'Dockerfile') docker_ref = ref.replace('/', '-') return f'docker://ghcr.io/{repo}:{docker_ref}' @@ -70,6 +72,20 @@ action = { }, } -action_path = pathlib.Path('.github/actions/run-docker-container/action.yml') +# The generated trampoline action must exist in the allowlisted +# runner-defined working directory so it can be referenced by the +# relative path starting with `./`. +# +# This mutates the end-user's workspace slightly but uses a path +# that is unlikely to clash with somebody else's use. +# +# We cannot use randomized paths because the composite action +# syntax does not allow accessing variables in `uses:`. This +# means that we end up having to hardcode this path both here and +# in `action.yml`. +action_path = pathlib.Path( + '.github/.tmp/.generated-actions/' + 'run-pypi-publish-in-docker-container/action.yml', +) action_path.parent.mkdir(parents=True, exist_ok=True) action_path.write_text(json.dumps(action, ensure_ascii=False), encoding='utf-8')