Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion .github/workflows/notify-qa.yml.template
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
name: Notify tutorials-qa
on:
push:
# -Contribution repos are a MIXTURE of default branches: most default to
# `main`, but Tutorials-Contribution still defaults to `master`. List BOTH
# so this fires ONLY on the repo's default branch — and NEVER on feature
# branches. Without this filter a push to any branch (e.g. the devtoberfest
# validation-tutorial bot's `validation-tutorial/*` branches) dispatches a
# QA rebuild for a slug that exists only on that branch; QA discovery reads
# the default branch, so the slug is a phantom and the rebuild hard-fails
# "unknown slug in filter" (tutorials-ims#2097). Mirrors the branch filter
# in docs/authors/tutorial-repo-dispatch.yml (the PROD notify template).
branches: [master, main]
paths:
- 'tutorials/**'

Expand All @@ -17,8 +27,15 @@ jobs:
changed=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }} \
| awk -F/ '/^tutorials\//{print $2}' | sort -u)
count=$(echo "$changed" | wc -l)
# Only emit a slug when EXACTLY one tutorial changed AND it matches the
# strict slug charset (whole-value POSIX case match); anything else →
# empty slug → rebuild-content-qa.yml runs a full rebuild. Mirrors
# docs/authors/tutorial-repo-dispatch.yml.
if [ "$count" = "1" ] && [ -n "$changed" ]; then
echo "slug=$changed" >> "$GITHUB_OUTPUT"
case "$changed" in
*[!a-z0-9-]* | -* ) echo "slug=" >> "$GITHUB_OUTPUT" ;;
*) echo "slug=$changed" >> "$GITHUB_OUTPUT" ;;
esac
else
echo "slug=" >> "$GITHUB_OUTPUT"
fi
Expand Down
27 changes: 27 additions & 0 deletions test/unit/install-notify-workflows.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,3 +392,30 @@ describe('PROD notify template branch trigger (regression guard)', () => {
expect(template).not.toMatch(/branches:\s*\[\s*main\s*\]/)
})
})

describe('QA notify template branch trigger (regression guard)', () => {
// -Contribution repos are ALSO a mixture of `main`- and `master`-default
// branches (Tutorials-Contribution defaults to `master`). The QA template
// MUST scope the push trigger to the default branch(es) — WITHOUT a branches:
// filter it fires on EVERY branch push (e.g. the devtoberfest validation-
// tutorial bot's `validation-tutorial/*` branches), dispatching a QA rebuild
// for a slug that exists only on that branch; QA discovery reads the default
// branch, so the slug is a phantom and the rebuild hard-fails "unknown slug
// in filter" (tutorials-ims#2097). Keep this in parity with the PROD guard.
const template = readFileSync(
join(__dirname, '..', '..', '.github', 'workflows', 'notify-qa.yml.template'),
'utf8',
)

it('fires on both master and main', () => {
expect(template).toMatch(/branches:\s*\[\s*master\s*,\s*main\s*\]/)
})

it('does not ship a main-only trigger', () => {
expect(template).not.toMatch(/branches:\s*\[\s*main\s*\]/)
})

it('ships a branches filter (never an unfiltered push trigger)', () => {
expect(template).toMatch(/branches:/)
})
})
Loading