diff --git a/.github/workflows/release-on-version.yml b/.github/workflows/release-on-version.yml new file mode 100644 index 0000000..0d5d293 --- /dev/null +++ b/.github/workflows/release-on-version.yml @@ -0,0 +1,117 @@ +--- +name: Release on version.js update + +on: + push: + branches: [ master ] + paths: + - 'public/js/version.js' + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + concurrency: + group: release-${{ github.ref }}-${{ github.sha }} + cancel-in-progress: false + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Read version from version.js + id: ver + shell: bash + run: | + set -euo pipefail + if [[ ! -f public/js/version.js ]]; then + echo "version.js not found"; exit 1 + fi + VER=$(grep -Eo "APP_VERSION\s*=\s*'v[^']+'" public/js/version.js | sed -E "s/.*'([^']+)'.*/\1/") + if [[ -z "$VER" ]]; then + echo "Could not parse APP_VERSION from version.js"; exit 1 + fi + echo "version=$VER" >> "$GITHUB_OUTPUT" + echo "Parsed version: $VER" + + - name: Skip if tag already exists + id: tagcheck + shell: bash + run: | + set -euo pipefail + git fetch --tags --quiet + if git rev-parse -q --verify "refs/tags/${{ steps.ver.outputs.version }}" >/dev/null; then + echo "exists=true" >> "$GITHUB_OUTPUT" + echo "Tag ${{ steps.ver.outputs.version }} already exists. Skipping release." + else + echo "exists=false" >> "$GITHUB_OUTPUT" + fi + + - name: Prepare release notes from CHANGELOG.md (optional) + if: steps.tagcheck.outputs.exists == 'false' + id: notes + shell: bash + run: | + set -euo pipefail + NOTES_PATH="" + if [[ -f CHANGELOG.md ]]; then + # Extract from first "## " until a line that is exactly "---" + awk ' + BEGIN{found=0} + /^## / && !found {found=1} + found && /^---$/ {exit} + found {print} + ' CHANGELOG.md > RELEASE_BODY.md || true + + # Clean up trailing blank lines + sed -i -e :a -e '/^\n*$/{$d;N;ba' -e '}' RELEASE_BODY.md || true + + if [[ -s RELEASE_BODY.md ]]; then + NOTES_PATH="RELEASE_BODY.md" + echo "Using extracted notes:" + head -n 60 RELEASE_BODY.md + else + echo "Top section not found or empty; will use auto-generated notes." + fi + else + echo "No CHANGELOG.md; will use auto-generated notes." + fi + + echo "path=${NOTES_PATH}" >> "$GITHUB_OUTPUT" + + - name: (optional) Build archive to attach + if: steps.tagcheck.outputs.exists == 'false' + shell: bash + run: | + set -euo pipefail + zip -r "FileRise-${{ steps.ver.outputs.version }}.zip" public/ README.md LICENSE >/dev/null || true + ls -l "FileRise-${{ steps.ver.outputs.version }}.zip" || true + + # Path A: we have extracted notes -> use body_path + - name: Create GitHub Release (with CHANGELOG snippet) + if: steps.tagcheck.outputs.exists == 'false' && steps.notes.outputs.path != '' + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ steps.ver.outputs.version }} + target_commitish: ${{ github.sha }} + name: ${{ steps.ver.outputs.version }} + body_path: ${{ steps.notes.outputs.path }} + generate_release_notes: false + files: | + FileRise-${{ steps.ver.outputs.version }}.zip + + # Path B: no notes -> let GitHub auto-generate from commits + - name: Create GitHub Release (auto notes) + if: steps.tagcheck.outputs.exists == 'false' && steps.notes.outputs.path == '' + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ steps.ver.outputs.version }} + target_commitish: ${{ github.sha }} + name: ${{ steps.ver.outputs.version }} + generate_release_notes: true + files: | + FileRise-${{ steps.ver.outputs.version }}.zip