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>
115 lines
3.7 KiB
Bash
Executable file
115 lines
3.7 KiB
Bash
Executable file
#!/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)"
|