Skip to content

Add a workflows-scripts action that returns the scripts of the running workflow commit - #345

Open
rnro wants to merge 4 commits into
swiftlang:mainfrom
rnro:self-repo-reference
Open

rnro wants to merge 4 commits into
swiftlang:mainfrom
rnro:self-repo-reference

Conversation

@rnro

@rnro rnro commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

A caller that pins a reusable workflow to a release gets the workflow YAML from that release, but the scripts the YAML runs come from a separate checkout of this repository with no ref:, so they come from the default branch and a tag does not pin them.

The new composite action locates the scripts and configuration files through github.action_path, which GitHub resolves for a $/ reference to this repository at the commit of the running workflow. An optional copy_into_workspace input copies the scripts into the workspace, for consumers that only see the workspace, and the action returns the scripts path in POSIX, Windows and workspace-relative forms.

This PR also adopts this change for soundness.yml, package_test.yml, toolchain_matrix.yml, benchmarks.yml and execute_matrix.yml. (It leaves swift_package_test.yml unchanged.)

This should resolve #334

rnro added 4 commits October 30, 2026 11:09
…ing commit

A caller that pins a reusable workflow to a release gets the workflow YAML from that release, but the scripts the YAML runs come from a separate checkout of this repository with no `ref:`, so they come from the default branch and a tag does not pin them.

The new composite action locates the scripts and configuration files through `github.action_path`, which GitHub resolves for a `$/` reference to this repository at the commit of the running workflow. An optional `copy_into_workspace` input copies the scripts into the workspace, for consumers that only see the workspace, and the action returns the scripts path in POSIX, Windows and workspace-relative forms.
`package_test.yml`, `toolchain_matrix.yml`, `benchmarks.yml` and `execute_matrix.yml` resolved their scripts with two steps that checked out the default branch of `workflows_repository`, so a release tag did not pin them. The two inputs existed only to point at a fork, which can instead be tested by calling its workflow at its own ref.

Replaced those steps with `uses: $/.github/actions/workflows-scripts`. The generator jobs run `generate-matrix.swift` straight from the action's directory. The `execute_matrix.yml` jobs ask for the copy in the workspace, so the Linux container mount, the Windows prefix translation and the FreeBSD VM's rsync of the workspace keep working without changes to the runner scripts. Removed `workflows_repository` and `workflows_ref` and their forwarding, and updated the FreeBSD test for the new relative directory.
Each soundness job that ran a script or read a default configuration file checked out `swiftlang/github-workflows` from the default branch, so a release of `soundness.yml` did not pin them.

Replaced the checkout and the script-root step in eight jobs with `uses: $/.github/actions/workflows-scripts` and read the scripts and configs from its outputs. The jobs use the action's own directory, with no copy, since none of them runs the scripts in another file system.
Requirement 3 of the architecture document said the scripts are checked out explicitly, which no longer describes how they are found. The document also never said what `$/` means, what the `workflows-scripts` action returns, or how to test a change now that `workflows_repository` and `workflows_ref` are gone.

Rewrote requirement 3 to state only the requirement, that the scripts come from the commit of the running workflow, and moved the mechanism into a "How workflows get their scripts" section. It explains `$/`, tabulates the action's input and outputs, notes that `execute_matrix.yml` copies the scripts for containers and the FreeBSD VM after the checkout, and says a change is tested by calling the workflow at its own branch or fork ref. Listed the action among the components.
@rnro
rnro requested a review from a team as a code owner October 30, 2026 15:19
Comment on lines 186 to +219
docs-check:
name: Documentation check
if: ${{ inputs.docs_check_enabled }}
runs-on: ubuntu-latest
container:
image: ${{ inputs.docs_check_container_image }}
timeout-minutes: 20
steps:
- name: Checkout repository
uses: actions/checkout@v7
with:
persist-credentials: false
submodules: true
- name: Checkout swiftlang/github-workflows repository
if: ${{ github.repository != 'swiftlang/github-workflows' }}
uses: actions/checkout@v7
with:
repository: swiftlang/github-workflows
path: github-workflows
- name: Determine script-root path
id: script_path
run: |
if [ "${{ github.repository }}" = "swiftlang/github-workflows" ]; then
echo "root=$GITHUB_WORKSPACE" >> $GITHUB_OUTPUT
else
echo "root=$GITHUB_WORKSPACE/github-workflows" >> $GITHUB_OUTPUT
fi
- name: Locate the workflows scripts
id: workflows_scripts
uses: $/.github/actions/workflows-scripts
- name: Run documentation check
env:
ADDITIONAL_DOCC_ARGUMENTS: ${{ inputs.docs_check_additional_arguments }}
DOCC_ANALYZE: ${{ inputs.docs_check_analyze }}
DOCS_TARGETS: ${{ inputs.docs_check_targets}}
SCRIPT_ROOT: ${{ steps.script_path.outputs.root }}
SCRIPTS_DIRECTORY: ${{ steps.workflows_scripts.outputs.scripts_directory }}
run: |
set -x
${{ inputs.linux_pre_build_command }}
analyze_arg=""
doc_target_arg=""
if [ "${DOCS_TARGETS}" != "" ] ; then
doc_target_arg="--doc-targets ${DOCS_TARGETS}"
fi
if [ "${DOCC_ANALYZE}" != "true" ]; then
analyze_arg="--no-analyze"
fi
"${SCRIPT_ROOT}/.github/workflows/scripts/check-docs.sh" ${analyze_arg} ${doc_target_arg} --additional-docc-arguments ${ADDITIONAL_DOCC_ARGUMENTS}
"${SCRIPTS_DIRECTORY}/check-docs.sh" ${analyze_arg} ${doc_target_arg} --additional-docc-arguments ${ADDITIONAL_DOCC_ARGUMENTS}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what we really want is to convert this run block into its own action and then this all simplifies to uses: $/.github/actions/docs-check. Actions should bundle all of their configuration files so the same works for e.g. flake8. However, there's also a trap where if we make structural changes then it breaks anybody who is using an older version and expects to be able to clone the scripts from main. I think that means we need to do it in two PRs across two versions?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing this would mean we'd need many actions though right? One for each run block we remove?

@madrob

madrob commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

Also may be worth looking at #220 and #236 (and #239) for how this broke when I tried it the first time (before local actions existed)

@rnro

rnro commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor Author

Also may be worth looking at #220 and #236 (and #239) for how this broke when I tried it the first time (before local actions existed)

As far as I can tell things broke because the scripts moved locations in #220, and up until this change everyone gets their scripts from main so moving them is a breaking change. This PR doesn't move the scripts, so existing users should be fine - and after this PR users will no longer be grabbing scripts from main so we will at some point be free to move them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A workflow pinned to a release tag takes its scripts from main

2 participants