Defensive CI/CD patterns: semver validation, token checks, retry logic, and draft detection
57
66%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./.copilot/skills/ci-validation-gates/SKILL.mdCI workflows must be defensive. These patterns capture lessons from prior release incidents; they are maintained as version-agnostic gates rather than claims about a particular repository release.
Every publish workflow MUST validate version format before npm publish. 4-part versions (e.g., 0.8.21.4) are NOT valid semver — npm mangles them.
- name: Validate semver
run: |
VERSION="${{ github.event.release.tag_name }}"
VERSION="${VERSION#v}"
if ! npx semver "$VERSION" > /dev/null 2>&1; then
echo "❌ Invalid semver: $VERSION"
echo "Only 3-part versions (X.Y.Z) or prerelease (X.Y.Z-tag.N) are valid."
exit 1
fi
echo "✅ Valid semver: $VERSION"NPM_TOKEN MUST be an Automation token, not a User token with 2FA:
npm registry uses eventual consistency. After npm publish succeeds, the package may not be immediately queryable.
- name: Verify package (with retry)
run: |
MAX_ATTEMPTS=5
WAIT_SECONDS=15
for attempt in $(seq 1 $MAX_ATTEMPTS); do
echo "Attempt $attempt/$MAX_ATTEMPTS: Checking $PACKAGE@$VERSION..."
if npm view "$PACKAGE@$VERSION" version > /dev/null 2>&1; then
echo "✅ Package verified"
exit 0
fi
[ $attempt -lt $MAX_ATTEMPTS ] && sleep $WAIT_SECONDS
done
echo "❌ Failed to verify after $MAX_ATTEMPTS attempts"
exit 1Draft releases don't emit release: published event. Workflows MUST:
release: published (NOT created)curl -f (normally curl -fsSL) so HTTP failures cannot be interpreted as scripts.set -euo pipefail in Bash steps. When a download must feed an extractor, pipefail
prevents the extractor from masking a failed download.The root build invokes scripts/bump-build.mjs, which can mutate package versions. Local
validation MUST set SKIP_BUILD_BUMP=1 (or use an existing CI environment that guarantees no
mutation) and MUST verify the package manifests and lockfile are unchanged afterward. Prefer an
affected workspace build when it covers the check. Never let a validation build rewrite package
versions or create a version-only diff.
| # | What Happened | Root Cause | Prevention |
|---|---|---|---|
| 1 | 4-part version published, npm mangled it | No semver validation gate | npx semver check before every publish |
| 2 | CI failed 5+ times with EOTP | User token with 2FA | Automation token only |
| 3 | Verify returned false 404 | No retry logic for propagation | 5 attempts, 15s intervals |
| 4 | Workflow never triggered | Draft release doesn't emit event | Never create draft releases |
29e69f5
Also appears in
last in sync Jul 27, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.