feat(ci): reusable ecosystem workflows + selftest (999_testing)
All checks were successful
CI / preflight (push) Successful in 7s
CI / typecheck (push) Successful in 17s
ecosystem-selftest / semantic-release-bumptest (push) Successful in 12s
pulumi-preview / preview (push) Successful in 20s
ecosystem-selftest / eslint-gate (push) Successful in 5s
ecosystem-selftest / yamllint-gate (push) Successful in 4s
All checks were successful
CI / preflight (push) Successful in 7s
CI / typecheck (push) Successful in 17s
ecosystem-selftest / semantic-release-bumptest (push) Successful in 12s
pulumi-preview / preview (push) Successful in 20s
ecosystem-selftest / eslint-gate (push) Successful in 5s
ecosystem-selftest / yamllint-gate (push) Successful in 4s
The ecosystem-CI architecture: reusable Forgejo workflows (on: workflow_call) that downstream repos reference as `uses: olsitec/foundation/.forgejo/workflows/<x>.yml@master`. - reusable-node-build.yml: install + build for npm/bun/none — covers the npm package (olsicrypto), bun package (document-engine), and no-artifact versioned (olsitrack/api) shapes. - reusable-docker-build.yml: docker build via the host socket (R5: trusted repos only until the runner is fenced) — the seaspots-homepage / token-service shape. - reusable-lint.yml: eslint + yamllint gate (either error → job non-zero). - reusable-semantic-release.yml: conventionalcommits-preset version probe (dry-run), faithful to the GitLab template; outputs the computed next version. Real Forgejo publishing deferred (no @semantic-release/forgejo analogue yet). - ecosystem-selftest.yml + ci/semantic-release-bumptest.sh: self-contained proof on the runner of the 999_testing acceptance criteria that need no external repo — the semantic-release bump sequence (1.0.0→1.1.0→1.1.1→2.0.0→3.0.0) and the eslint/yamllint non-zero-exit gates. Validated in a foundation-ci container. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f5f9d1f8a5
commit
f9aecf1b18
6 changed files with 450 additions and 0 deletions
115
ci/semantic-release-bumptest.sh
Executable file
115
ci/semantic-release-bumptest.sh
Executable file
|
|
@ -0,0 +1,115 @@
|
|||
#!/usr/bin/env bash
|
||||
# semantic-release-bumptest.sh — prove semantic-release computes the version bumps
|
||||
# Olsitec expects (documentation/999_testing.md "semantic-release testing").
|
||||
#
|
||||
# Uses the SAME releaserc + `--dry-run --no-ci --tag-format '${version}'` technique
|
||||
# as the canonical GitLab template (olsitec/gitlab ci_templates/release-automation/
|
||||
# semantic-release.yaml): conventionalcommits preset + the custom releaseRules
|
||||
# (feat→minor, fix/chore→patch, breaking→major, BREAKING CHANGE/BREAKING CHANGES
|
||||
# footers→major). Self-contained — builds a throwaway repo + bare origin, walks the
|
||||
# conventional-commit sequence, and asserts:
|
||||
# init → 1.0.0 · feat → 1.1.0 · fix/chore → 1.1.1 · feat! → 2.0.0 · BREAKING → 3.0.0
|
||||
# Exits non-zero on the first mismatch. Runs in the foundation-ci image (which bakes
|
||||
# semantic-release + the conventionalcommits preset).
|
||||
set -euo pipefail
|
||||
|
||||
WORK=$(mktemp -d)
|
||||
trap 'rm -rf "$WORK"' EXIT
|
||||
REPO="$WORK/repo"
|
||||
BARE="$WORK/origin.git"
|
||||
BRANCH=master
|
||||
|
||||
git init -q --bare "$BARE"
|
||||
git init -q -b "$BRANCH" "$REPO"
|
||||
cd "$REPO"
|
||||
git config user.email ci@olsitec.de
|
||||
git config user.name "CI Bumptest"
|
||||
git remote add origin "$BARE"
|
||||
|
||||
# The releaserc Olsitec uses (trimmed to the version-COMPUTE plugins: the host
|
||||
# publish plugins are irrelevant to a dry-run bump check and would need a token).
|
||||
cat > .releaserc.yaml <<'EOF'
|
||||
branches:
|
||||
- name: master
|
||||
tagFormat: "${version}"
|
||||
plugins:
|
||||
- - "@semantic-release/commit-analyzer"
|
||||
- preset: conventionalcommits
|
||||
releaseRules:
|
||||
- breaking: true
|
||||
release: major
|
||||
- type: breaking
|
||||
release: major
|
||||
- type: feature
|
||||
release: minor
|
||||
- type: feat
|
||||
release: minor
|
||||
- type: fix
|
||||
release: patch
|
||||
- type: build
|
||||
release: patch
|
||||
- type: chore
|
||||
release: patch
|
||||
- type: ci
|
||||
release: patch
|
||||
- type: docs
|
||||
release: patch
|
||||
- type: perf
|
||||
release: patch
|
||||
- type: refactor
|
||||
release: patch
|
||||
- type: style
|
||||
release: patch
|
||||
- type: test
|
||||
release: patch
|
||||
parserOpts:
|
||||
noteKeywords:
|
||||
- BREAKING CHANGE
|
||||
- BREAKING CHANGES
|
||||
- "@semantic-release/release-notes-generator"
|
||||
EOF
|
||||
git add -A
|
||||
git commit -q -m "chore: scaffold releaserc"
|
||||
|
||||
# Echo the version semantic-release would publish next (dry-run), or "" if none.
|
||||
compute() {
|
||||
out=$(semantic-release --dry-run --no-ci --tag-format '${version}' --branches "$BRANCH" 2>&1 || true)
|
||||
# semantic-release logs e.g. "The next release version is 1.1.0"
|
||||
printf '%s\n' "$out" \
|
||||
| grep -oiE 'next release version is [0-9]+\.[0-9]+\.[0-9]+' \
|
||||
| grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | tail -1
|
||||
}
|
||||
|
||||
FAILED=0
|
||||
# step <expected> <commit-subject> [body]
|
||||
step() {
|
||||
exp="$1"; subj="$2"; body="${3:-}"
|
||||
if [ -n "$body" ]; then
|
||||
git commit -q --allow-empty -m "$subj" -m "$body"
|
||||
else
|
||||
git commit -q --allow-empty -m "$subj"
|
||||
fi
|
||||
git push -q origin "$BRANCH"
|
||||
got=$(compute)
|
||||
if [ "$got" = "$exp" ]; then
|
||||
echo " OK '$subj' → $got"
|
||||
git tag "$got" # simulate the published release (bare tag)
|
||||
git push -q origin "$got"
|
||||
else
|
||||
echo " FAIL '$subj' → expected $exp, got '${got:-<none>}'"
|
||||
FAILED=1
|
||||
fi
|
||||
}
|
||||
|
||||
echo "semantic-release bump sequence (999_testing):"
|
||||
step 1.0.0 "feat: initial release"
|
||||
step 1.1.0 "feat: add a feature"
|
||||
step 1.1.1 "fix: correct a bug"
|
||||
step 2.0.0 "feat!: breaking redesign"
|
||||
step 3.0.0 "feat: another change" "BREAKING CHANGE: drops the old API"
|
||||
|
||||
if [ "$FAILED" -ne 0 ]; then
|
||||
echo "semantic-release bumptest: FAILED"
|
||||
exit 1
|
||||
fi
|
||||
echo "semantic-release bumptest: PASS (1.0.0 → 1.1.0 → 1.1.1 → 2.0.0 → 3.0.0)"
|
||||
Loading…
Add table
Add a link
Reference in a new issue