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_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 @@ def set_image(ref: str, repo: str, repo_id: str) -> str: }, } -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')