mirror of
https://github.com/opensourcepos/opensourcepos.git
synced 2026-11-08 23:43:32 -05:00
- release.yml:
- Normalize App.php, package.json, and package-lock.json to clean release version ($TARGET) prior to tagging, ensuring tagged commits contain clean release metadata in git history.
- Update release commit message to `chore(release): release <version>` to reflect that code, manifests, and templates are committed.
- Automate updating issue templates (bug report.yml and feature_request.yml) on release: prepends new release, retains top 5 versions, and preserves the fallback option.
- Automate updating supported versions in SECURITY.md (>= $TARGET and < $TARGET).
- Remove automated regex update of README.md: the intro sentence describes the v3.4 rewrite to CI4, so blindly regex-replacing the version on future releases produces misleading prose and is brittle against wording edits.
- Add concurrency group `release` and restrict workflow execution to master branch.
- Bump App.php, package.json, and package-lock.json to next dev snapshot ($NEXT) in post-release commit.
- build-release.yml:
- Remove redundant VERSION="${VERSION%-dev}" check and in-runner normalization step now that release commits are clean.
- Templates and Security Policy:
- Add OpenSourcePOS 3.4.3 to bug report.yml, feature_request.yml, and SECURITY.md.
- Add "- Older version (specify in description)" fallback option to issue templates.
- Remove default selection in bug report.yml so reporters specify version explicitly.
208 lines
9.1 KiB
YAML
208 lines
9.1 KiB
YAML
name: Release
|
|
|
|
# Cuts the current release (changelog + tag + draft release) and, optionally,
|
|
# bumps master to the next dev version. One workflow, full release cycle.
|
|
#
|
|
# Flow:
|
|
# 1. Release current version:
|
|
# - generate git-cliff changelog section (base..HEAD)
|
|
# - insert it into CHANGELOG.md + GFM compare refs
|
|
# - normalize source version to clean release (strip -dev)
|
|
# - update issue templates / SECURITY.md
|
|
# - commit + push the release commit
|
|
# - tag the current version and push the tag with the repo PAT
|
|
# (a PAT push triggers build-release.yml, whose official-release job
|
|
# creates the DRAFT GitHub Release with the changelog + assets)
|
|
# 2. (optional) bump to the next dev version:
|
|
# - bump App.php / package.json / package-lock.json to next dev snapshot
|
|
# - commit + push
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
next_bump:
|
|
description: 'After cutting this release, bump master to the next dev version'
|
|
required: true
|
|
type: choice
|
|
options:
|
|
- patch
|
|
- minor
|
|
- major
|
|
- skip
|
|
default: 'patch'
|
|
|
|
concurrency:
|
|
group: release
|
|
cancel-in-progress: false
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
jobs:
|
|
release:
|
|
name: Cut release and bump next version
|
|
runs-on: ubuntu-22.04
|
|
if: github.ref == 'refs/heads/master'
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
# Use the repo PAT (an admin token) so the changelog + bump pushes
|
|
# below can update the protected master branch (enforce_admins is off).
|
|
# GITHUB_TOKEN cannot, because master requires a PR review.
|
|
token: ${{ secrets.TOKEN }}
|
|
|
|
- name: Install git-cliff
|
|
run: |
|
|
V=2.14.2
|
|
curl -sLSfL "https://github.com/orhun/git-cliff/releases/download/v${V}/git-cliff-${V}-x86_64-unknown-linux-musl.tar.gz" -o /tmp/cliff.tar.gz
|
|
tar xzf /tmp/cliff.tar.gz -C /tmp
|
|
mv "/tmp/git-cliff-${V}/git-cliff" /usr/local/bin/git-cliff
|
|
chmod +x /usr/local/bin/git-cliff
|
|
git cliff --version
|
|
|
|
- name: Determine version
|
|
id: version
|
|
run: |
|
|
APP_VERSION=$(grep "application_version" app/Config/App.php | sed "s/.*= '\(.*\)';/\1/g")
|
|
# Master carries a -dev snapshot suffix; strip it for the release target.
|
|
TARGET="${APP_VERSION%-dev}"
|
|
if ! [[ "$TARGET" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
echo "ERROR: target '$TARGET' is not in X.Y.Z form"; exit 1
|
|
fi
|
|
BASE=$(git tag --list | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -1)
|
|
if [ -z "$BASE" ]; then
|
|
echo "ERROR: no previous release tag found"; exit 1
|
|
fi
|
|
if [ "$BASE" = "$TARGET" ]; then
|
|
echo "ERROR: target $TARGET equals base $BASE; nothing to release"; exit 1
|
|
fi
|
|
if ! printf '%s\n%s\n' "$BASE" "$TARGET" | sort -VC 2>/dev/null; then
|
|
echo "ERROR: target $TARGET is not greater than base $BASE"; exit 1
|
|
fi
|
|
echo "target=$TARGET" >> "$GITHUB_OUTPUT"
|
|
echo "base=$BASE" >> "$GITHUB_OUTPUT"
|
|
echo "Releasing $TARGET (previous release: $BASE)"
|
|
|
|
- name: Generate changelog section
|
|
run: |
|
|
git cliff --config cliff.toml \
|
|
--tag "${{ steps.version.outputs.target }}" \
|
|
--output /tmp/section.md \
|
|
"${{ steps.version.outputs.base }}..HEAD"
|
|
sed -i '/./,$!d' /tmp/section.md
|
|
echo "Generated $(grep -c '^- ' /tmp/section.md) entries"
|
|
echo "=== first 5 ==="
|
|
head -5 /tmp/section.md
|
|
|
|
- name: Insert into CHANGELOG.md
|
|
run: |
|
|
TARGET="${{ steps.version.outputs.target }}"
|
|
BASE="${{ steps.version.outputs.base }}"
|
|
sed -i "/^\[unreleased\]:/a [${TARGET}]: https://github.com/opensourcepos/opensourcepos/compare/${BASE}...${TARGET}" CHANGELOG.md
|
|
sed -i "s|^\[unreleased\]:.*|\[unreleased\]: https://github.com/opensourcepos/opensourcepos/compare/${TARGET}...HEAD|" CHANGELOG.md
|
|
LINE=$(grep -nE '^## \[[0-9]+\.' CHANGELOG.md | head -1 | cut -d: -f1)
|
|
printf '%s\n\n' "$(cat /tmp/section.md)" > /tmp/section_final.md
|
|
sed -i "$((LINE-1))r /tmp/section_final.md" CHANGELOG.md
|
|
echo "Inserted $TARGET section before line $LINE"
|
|
|
|
- name: Commit release and docs
|
|
run: |
|
|
TARGET="${{ steps.version.outputs.target }}"
|
|
|
|
# Normalize source version to clean release version so git tag does not carry -dev suffix
|
|
sed -i "s/public string \\\$application_version = '[^']*';/public string \\\$application_version = '$TARGET';/" app/Config/App.php
|
|
sed -i "s/\"version\": \"[^\"]*\",/\"version\": \"$TARGET\",/" package.json
|
|
awk -v v="$TARGET" '
|
|
/"name": "@opensourcepos\/opensourcepos"/ { expect=1 }
|
|
expect && /"version": / { sub(/"version": "[^"]*"/, "\"version\": \"" v "\""); expect=0 }
|
|
{ print }
|
|
' package-lock.json > .package-lock.tmp && mv .package-lock.tmp package-lock.json
|
|
|
|
# Update SECURITY.md supported version to current release
|
|
sed -i -E "s/>= [0-9]+\.[0-9]+\.[0-9]+/>= $TARGET/" SECURITY.md
|
|
sed -i -E "s/< [0-9]+\.[0-9]+\.[0-9]+/< $TARGET/" SECURITY.md
|
|
|
|
# Update issue templates with the released version
|
|
for template in ".github/ISSUE_TEMPLATE/bug report.yml" ".github/ISSUE_TEMPLATE/feature_request.yml"; do
|
|
[ -f "$template" ] || continue
|
|
awk -v v="$TARGET" -v max=5 '
|
|
BEGIN { in_opts=0; count=0 }
|
|
/id: ospos-version/ { in_opts=1 }
|
|
in_opts && /- (master \/ )?development \(unreleased\)/ {
|
|
print
|
|
print " - OpenSourcePOS " v
|
|
next
|
|
}
|
|
in_opts && /^[ ]*- OpenSourcePOS / {
|
|
if ($0 ~ "OpenSourcePOS " v "$") next
|
|
count++
|
|
if (count < max) print
|
|
next
|
|
}
|
|
in_opts && /^[ ]*(default:|validations:|- type:|- Other|- Older)/ {
|
|
in_opts=0
|
|
print
|
|
next
|
|
}
|
|
{ print }
|
|
' "$template" > "$template.tmp" && mv "$template.tmp" "$template"
|
|
done
|
|
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
git add CHANGELOG.md app/Config/App.php package.json package-lock.json SECURITY.md .github/ISSUE_TEMPLATE/
|
|
git commit -m "chore(release): release ${{ steps.version.outputs.target }}"
|
|
git push origin HEAD
|
|
|
|
- name: Tag and push (PAT triggers build-release.yml)
|
|
run: |
|
|
TAG="${{ steps.version.outputs.target }}"
|
|
git tag "$TAG"
|
|
# Push with the repo PAT (not GITHUB_TOKEN) so the tag-push event
|
|
# triggers build-release.yml, whose official-release job creates the
|
|
# draft release with the changelog and assets.
|
|
git push "https://x-access-token:${RELEASE_PAT}@github.com/opensourcepos/opensourcepos.git" "refs/tags/$TAG"
|
|
echo "Released $TAG — draft release will be created by build-release.yml"
|
|
env:
|
|
RELEASE_PAT: ${{ secrets.TOKEN }}
|
|
|
|
- name: Bump to next dev version (optional)
|
|
if: ${{ inputs.next_bump != 'skip' }}
|
|
run: |
|
|
CURRENT="${{ steps.version.outputs.target }}"
|
|
MAJOR=$(echo "$CURRENT" | cut -d. -f1)
|
|
MINOR=$(echo "$CURRENT" | cut -d. -f2)
|
|
PATCH=$(echo "$CURRENT" | cut -d. -f3)
|
|
case "${{ inputs.next_bump }}" in
|
|
major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0 ;;
|
|
minor) MINOR=$((MINOR + 1)); PATCH=0 ;;
|
|
patch) PATCH=$((PATCH + 1)) ;;
|
|
*) echo "ERROR: unknown bump type ${{ inputs.next_bump }}"; exit 1 ;;
|
|
esac
|
|
NEXT="${MAJOR}.${MINOR}.${PATCH}-dev"
|
|
echo "Bumping to next dev version $NEXT"
|
|
|
|
sed -i "s/public string \\\$application_version = '[^']*';/public string \\\$application_version = '$NEXT';/" app/Config/App.php
|
|
sed -i "s/\"version\": \"[^\"]*\",/\"version\": \"$NEXT\",/" package.json
|
|
# Keep package-lock.json in sync: bump only the @opensourcepos/opensourcepos
|
|
# package version (top-level + packages.""), leave dependency versions alone.
|
|
awk -v v="$NEXT" '
|
|
/"name": "@opensourcepos\/opensourcepos"/ { expect=1 }
|
|
expect && /"version": / { sub(/"version": "[^"]*"/, "\"version\": \"" v "\""); expect=0 }
|
|
{ print }
|
|
' package-lock.json > .package-lock.tmp && mv .package-lock.tmp package-lock.json
|
|
|
|
echo "=== version refs after bump ==="
|
|
grep "application_version" app/Config/App.php
|
|
grep '"version"' package.json | head -1
|
|
grep -A1 '"name": "@opensourcepos/opensourcepos"' package-lock.json
|
|
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
git add app/Config/App.php package.json package-lock.json
|
|
git commit -m "chore: bump version to $NEXT"
|
|
git push origin HEAD
|