Skip to content

Merge pull request #10 from Timwood0x10/dev #63

Merge pull request #10 from Timwood0x10/dev

Merge pull request #10 from Timwood0x10/dev #63

Workflow file for this run

# Push to main: lint → CI (build + test + package) → auto release draft
name: Build & Test
on:
push:
branches: [main]
permissions:
contents: read
actions: write
concurrency:
group: build-${{ github.sha }}
cancel-in-progress: true
jobs:
lint:
uses: ./.github/workflows/_lint.yml
ci:
needs: [lint]
if: ${{ !cancelled() && needs.lint.result == 'success' }}
uses: ./.github/workflows/_ci.yml
with:
skip_perf: true
skip_package: false
# ── Auto create draft release ──
release-draft:
needs: [ci]
if: ${{ !cancelled() && needs.ci.result == 'success' }}
runs-on: ubuntu-24.04
timeout-minutes: 15
permissions:
contents: write
actions: read
steps:
- uses: actions/checkout@v7 # v4.2.2
with:
fetch-depth: 0
- uses: actions/download-artifact@v8 # v4.2.1
with:
merge-multiple: true
path: artifacts
- name: Read version from RELEASE.md
id: version
run: |
VERSION=$(head -1 RELEASE.md | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' || echo "unknown")
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Detected version: $VERSION"
- name: Validate version
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
# Reject "unknown" or invalid semver
if [ "$VERSION" = "unknown" ] || ! echo "$VERSION" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then
echo "ERROR: Invalid version '$VERSION'. RELEASE.md line 1 must be '# CodeScope vX.Y.Z'"
exit 1
fi
# Check monotonicity: version must be > latest tag
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
echo "Latest tag: $LATEST_TAG, new version: $VERSION"
# Compare semver (strip leading 'v', compare major.minor.patch)
NEW_VER="${VERSION#v}"
OLD_VER="${LATEST_TAG#v}"
NEW_MAJOR=$(echo "$NEW_VER" | cut -d. -f1)
NEW_MINOR=$(echo "$NEW_VER" | cut -d. -f2)
NEW_PATCH=$(echo "$NEW_VER" | cut -d. -f3)
OLD_MAJOR=$(echo "$OLD_VER" | cut -d. -f1)
OLD_MINOR=$(echo "$OLD_VER" | cut -d. -f2)
OLD_PATCH=$(echo "$OLD_VER" | cut -d. -f3)
IS_NEWER=false
if [ "$NEW_MAJOR" -gt "$OLD_MAJOR" ]; then
IS_NEWER=true
elif [ "$NEW_MAJOR" -eq "$OLD_MAJOR" ] && [ "$NEW_MINOR" -gt "$OLD_MINOR" ]; then
IS_NEWER=true
elif [ "$NEW_MAJOR" -eq "$OLD_MAJOR" ] && [ "$NEW_MINOR" -eq "$OLD_MINOR" ] && [ "$NEW_PATCH" -gt "$OLD_PATCH" ]; then
IS_NEWER=true
fi
if [ "$IS_NEWER" = "false" ]; then
echo "ERROR: Version $VERSION is not greater than latest tag $LATEST_TAG"
echo "Versions must be monotonically increasing."
exit 1
fi
echo "✓ Version $VERSION is valid and greater than $LATEST_TAG"
- name: Check if release already exists
id: check_release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ steps.version.outputs.version }}
run: |
if gh release view "$VERSION" >/dev/null 2>&1; then
echo "exists=true" >> "$GITHUB_OUTPUT"
echo "Release $VERSION already exists, skipping"
else
echo "exists=false" >> "$GITHUB_OUTPUT"
fi
- name: Write release notes to file
if: steps.check_release.outputs.exists != 'true'
run: |
tail -n +2 RELEASE.md > /tmp/release_body.md
echo "Release body written ($(wc -c < /tmp/release_body.md) bytes)"
- name: Generate combined checksums
if: steps.check_release.outputs.exists != 'true'
run: |
cd artifacts
sha256sum *.tar.gz > ../checksums.txt
- name: Create tag
if: steps.check_release.outputs.exists != 'true'
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"
# Non-destructive: only create the tag if it does not already exist
# (e.g. a previous run created the tag but failed before the release).
if git rev-parse "$VERSION" >/dev/null 2>&1; then
echo "Tag $VERSION already exists locally, skipping creation"
else
git tag "$VERSION" -m "Release $VERSION"
fi
# No --force: a divergent remote tag must surface as a loud failure
# rather than silently overwriting published history.
git push origin "$VERSION"
- name: Create Draft Release
if: steps.check_release.outputs.exists != 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ steps.version.outputs.version }}
run: |
gh release create "$VERSION" \
--draft \
--title "$VERSION" \
--notes-file /tmp/release_body.md \
artifacts/*.tar.gz \
checksums.txt
echo "✅ Release $VERSION created with binaries"