Skip to content

Commit ba75778

Browse files
authored
fix: release-doc-sync action checkout pollutes caller's working tree (#20)
The composite action was checking out the meta-repo to a path inside GITHUB_WORKSPACE (.release-doc-sync). The caller's release.yml does git add -A after the action runs, which picked up the directory as a 160000-mode gitlink (submodule pointer to meta-repo HEAD SHA). Every release commit was polluted with this stale pointer. Fix: move the meta-repo checkout to ${{ runner.temp }}/release-doc-sync, which is outside the workspace and not visible to the caller's git add. The action's run step's working-directory updated to match. Surfaced during Phase 2b smoke test on Docker (#5). Caught before Phase 2c parallel rollout could propagate the pollution to 5 more tool repos. Adds a regression test guarding against future re-introduction. Signed-off-by: 154358121+TMHSDigital@users.noreply.github.com Made-with: Cursor Signed-off-by: 154358121+TMHSDigital@users.noreply.github.com
1 parent b05e0f0 commit ba75778

3 files changed

Lines changed: 45 additions & 7 deletions

File tree

.github/actions/release-doc-sync/action.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,17 @@ runs:
8787
using: 'composite'
8888
steps:
8989
# The sync script lives in this repo. Whether the caller is the meta-repo
90-
# itself or a tool repo, we always need the script at a known path. Use a
91-
# dedicated subdirectory so we do not clobber the caller's own checkout
92-
# (which lives at GITHUB_WORKSPACE).
90+
# itself or a tool repo, we always need the script at a known path. Check
91+
# out to runner.temp (OUTSIDE GITHUB_WORKSPACE) so the caller's release
92+
# commit step (typically `git add -A`) does not pick up the meta-repo
93+
# checkout as a 160000-mode gitlink. See v1.8.1 changelog for the bug
94+
# this avoids; regression-tested in tests/test_release_doc_sync.py.
9395
- name: Checkout release-doc-sync script
9496
uses: actions/checkout@v5
9597
with:
9698
repository: TMHSDigital/Developer-Tools-Directory
9799
ref: ${{ inputs.meta-repo-ref }}
98-
path: .release-doc-sync
100+
path: ${{ runner.temp }}/release-doc-sync
99101

100102
- name: Set up Python
101103
uses: actions/setup-python@v5
@@ -105,7 +107,7 @@ runs:
105107
- name: Run release-doc-sync
106108
id: run
107109
shell: bash
108-
working-directory: .release-doc-sync
110+
working-directory: ${{ runner.temp }}/release-doc-sync
109111
env:
110112
PLUGIN_VERSION: ${{ inputs.plugin-version }}
111113
PREVIOUS_VERSION: ${{ inputs.previous-version }}

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.8.0
1+
1.8.1

tests/test_release_doc_sync.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,13 +690,49 @@ def test_steps_follow_drift_check_pattern(self, action_doc):
690690

691691
checkout_step = next(s for s in steps if "actions/checkout" in s.get("uses", ""))
692692
assert checkout_step["with"]["repository"] == "TMHSDigital/Developer-Tools-Directory"
693-
assert checkout_step["with"]["path"] == ".release-doc-sync"
694693

695694
shell_runs = [s.get("run", "") for s in steps if "run" in s]
696695
assert any("scripts/release_doc_sync/sync.py" in r for r in shell_runs), (
697696
"no step invokes the sync script"
698697
)
699698

699+
def test_meta_repo_checkout_is_outside_workspace(self, action_doc):
700+
"""v1.8.1 regression guard. The meta-repo checkout MUST land outside
701+
GITHUB_WORKSPACE (i.e., under runner.temp), otherwise the caller's
702+
release commit step does `git add -A`, picks up the checkout
703+
directory, and writes it into the release commit as a 160000-mode
704+
gitlink. That polluted every Docker release commit pre-v1.8.1.
705+
706+
Both the checkout's `path:` and the run step's `working-directory:`
707+
must reference runner.temp so they stay in lock-step."""
708+
steps = action_doc["runs"]["steps"]
709+
710+
checkout_step = next(s for s in steps if "actions/checkout" in s.get("uses", ""))
711+
checkout_path = checkout_step["with"]["path"]
712+
assert "runner.temp" in checkout_path, (
713+
f"Meta-repo checkout path must be under ${{{{ runner.temp }}}} to avoid "
714+
f"polluting the caller's release commit with a gitlink. "
715+
f"Got: {checkout_path!r}. See v1.8.1 / DTD#5 Phase 2b."
716+
)
717+
assert not checkout_path.startswith("."), (
718+
f"Meta-repo checkout path must not be a workspace-relative dotted path "
719+
f"(those land inside GITHUB_WORKSPACE). Got: {checkout_path!r}."
720+
)
721+
722+
run_step = next(
723+
s for s in steps
724+
if s.get("id") == "run" or "sync.py" in s.get("run", "")
725+
)
726+
wd = run_step.get("working-directory", "")
727+
assert "runner.temp" in wd, (
728+
f"Run step's working-directory must match the checkout path "
729+
f"(both under ${{{{ runner.temp }}}}). Got: {wd!r}."
730+
)
731+
assert checkout_path == wd, (
732+
f"Checkout path and run working-directory must be identical "
733+
f"(checkout={checkout_path!r}, working-directory={wd!r})."
734+
)
735+
700736
def test_action_does_not_request_github_token(self, action_doc):
701737
"""The action runs inside the caller's release.yml and edits files
702738
in-place; the caller's existing 'Commit and tag' step picks them

0 commit comments

Comments
 (0)