Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions .github/workflows/build-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ name: Build & Release APK

on:
push:
branches: [main, Dev]
branches: [main, dev]
tags:
- 'v*'
pull_request:
branches: [main]
branches: [main, dev]

permissions:
contents: write
Expand Down Expand Up @@ -56,7 +56,7 @@ jobs:
build:
name: Build APK
needs: test
# Run when tests pass (PR), or when tests were skipped (push to main/Dev/tags).
# Run when tests pass (PR), or when tests were skipped (push to main/dev/tags).
# Block only on actual test failure or cancellation.
if: ${{ always() && needs.test.result != 'failure' && needs.test.result != 'cancelled' }}
runs-on: ubuntu-latest
Expand All @@ -74,12 +74,19 @@ jobs:
id: tag
run: |
set -euo pipefail
# Three release lanes (everything else is build-only):
# v* tag push -> production-named release, NOT prerelease
# push to main -> auto-bumped v* tag, NOT prerelease
# push to dev -> dev-<run_number> tag, PRERELEASE
# Prereleases are still uploaded to Play internal but with a
# distinct releaseName so they're easy to tell apart from the
# v*-named candidates we'd actually promote to production.
if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then
# Manual tag push — release as that tag
echo "release_tag=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
echo "should_release=true" >> "$GITHUB_OUTPUT"
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
elif [[ "${GITHUB_EVENT_NAME}" == "push" && "${GITHUB_REF}" == "refs/heads/main" ]]; then
# Push to main — auto-bump patch from latest v* tag
# Auto-bump patch from latest v* tag.
latest=$(git tag --list 'v*' --sort=-v:refname | head -n1)
if [[ -z "$latest" ]]; then
new_tag="v0.1"
Expand All @@ -93,10 +100,21 @@ jobs:
echo "Latest tag: ${latest:-<none>} -> new tag: $new_tag"
echo "release_tag=$new_tag" >> "$GITHUB_OUTPUT"
echo "should_release=true" >> "$GITHUB_OUTPUT"
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
elif [[ "${GITHUB_EVENT_NAME}" == "push" && "${GITHUB_REF}" == "refs/heads/dev" ]]; then
# dev pushes get a run-numbered tag and are flagged as prereleases.
# Distinct prefix so they sort separately from v* in GitHub releases
# and so the Play Console releaseName disambiguates them from
# main-branch release candidates.
new_tag="dev-${GITHUB_RUN_NUMBER}"
echo "release_tag=$new_tag" >> "$GITHUB_OUTPUT"
echo "should_release=true" >> "$GITHUB_OUTPUT"
echo "is_prerelease=true" >> "$GITHUB_OUTPUT"
else
# PR or Dev push — build only, no release
# PR or other branch push — build only, no release
echo "release_tag=" >> "$GITHUB_OUTPUT"
echo "should_release=false" >> "$GITHUB_OUTPUT"
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
fi

- name: Set up JDK 17
Expand Down Expand Up @@ -186,6 +204,10 @@ jobs:
tag_name: ${{ steps.tag.outputs.release_tag }}
files: ft8cn/app/build/outputs/apk/release/FT8CN-*.apk
generate_release_notes: true
# dev-* releases are flagged as prerelease so they sort under the
# latest v* and don't get picked up by downstream tooling that
# looks for "latest release".
prerelease: ${{ steps.tag.outputs.is_prerelease == 'true' }}
append_body: true
body: |

Expand Down
31 changes: 31 additions & 0 deletions .github/workflows/main-gate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Main branch source gate

# Enforces release discipline: PRs targeting main must come from `dev`.
# Feature branches are expected to land on dev first; only dev → main is
# allowed as the "promote to production" step, gated by branch protection
# requiring this status check.
#
# To enforce it: GitHub → Settings → Branches → Branch protection rule for
# `main` → Require status checks to pass → add "Main branch source gate /
# enforce-source-is-dev" to the required list.

on:
pull_request:
branches: [main]

jobs:
enforce-source-is-dev:
name: enforce-source-is-dev
runs-on: ubuntu-latest
steps:
- name: Check PR head branch
env:
HEAD_REF: ${{ github.head_ref }}
run: |
set -euo pipefail
if [[ "${HEAD_REF}" != "dev" ]]; then
echo "::error title=PR source must be dev::PRs to main are only allowed from the dev branch. Source branch: ${HEAD_REF}"
echo "Land your changes on dev first (PR from your feature branch into dev), then open dev → main."
exit 1
fi
echo "OK — PR source is dev."
Loading