Skip to content

refactor: unify release workflow to tag-based trigger#521

Merged
grunch merged 3 commits into
mainfrom
refactor/unified-release-workflow-520
Mar 9, 2026
Merged

refactor: unify release workflow to tag-based trigger#521
grunch merged 3 commits into
mainfrom
refactor/unified-release-workflow-520

Conversation

@mostronatorcoder

@mostronatorcoder mostronatorcoder Bot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor

Closes #520

Summary

Unifies the release process into a single tag-based workflow. Before: 3 manual steps (edit pubspec.yaml, push to main, create tag). After: 1 step (git tag v1.2.1 && git push --tags).

Changes

.github/workflows/release.yml (NEW)

Single tag-based workflow that:

  1. Extracts version from tag
  2. Generates categorized changelog from commits between tags
  3. Updates pubspec.yaml and commits to main
  4. Verifies signing secrets (fail-fast)
  5. Builds APK (split per ABI) + AAB with signing
  6. Verifies APK signatures
  7. Creates GitHub Release with all artifacts + release notes
  8. Triggers desktop builds via repository_dispatch
  9. Cleans up keystore files

.github/workflows/main.yml (SIMPLIFIED)

  • Removed all release logic (version detection, signing, APK build, GitHub Release creation)
  • Now serves as a CI build check only (debug build on push to main)
  • Ensures main branch always compiles

.github/workflows/desktop.yml (UPDATED)

  • Removed direct tag push trigger (was duplicating the release trigger)
  • Now triggered only via repository_dispatch from release.yml + manual workflow_dispatch
  • Build logic unchanged

.github/workflows/flutter.yml (UNCHANGED)

  • PR CI stays the same

Signing

Same secrets as before — no changes needed:

  • ANDROID_KEYSTORE_FILE
  • ANDROID_KEYSTORE_PASSWORD
  • ANDROID_KEY_PASSWORD
  • ANDROID_KEY_ALIAS

Release Flow

# That's it. Everything else is automatic.
git tag v1.2.1 && git push --tags

The workflow will: build Android APKs → verify signing → generate changelog → update pubspec.yaml on main → create GitHub Release → trigger desktop builds.

Testing

  • First release with this workflow will validate the full flow
  • workflow_dispatch on release.yml is NOT enabled intentionally (releases should always come from tags)
  • Desktop builds can still be triggered manually via workflow_dispatch on desktop.yml

Summary by CodeRabbit

  • Chores
    • Restructured CI/CD workflows to separate build checks from release processes, enabling automated versioning and artifact generation for tagged releases.
    • Simplified the main build pipeline to focus on verification checks.

Closes #520

- Add release.yml: single tag-based workflow that builds Android APK/AAB,
  generates changelog, updates pubspec.yaml, creates GitHub Release, and
  triggers desktop builds via repository_dispatch
- Simplify main.yml: remove release logic, keep as CI build check only
- Update desktop.yml: remove direct tag trigger (now triggered by
  release.yml via repository_dispatch + manual workflow_dispatch)

Release flow: git tag v1.2.1 && git push --tags → everything automatic
@grunch

grunch commented Mar 9, 2026

Copy link
Copy Markdown
Member

@coderabbitai review

1 similar comment
@grunch

grunch commented Mar 9, 2026

Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 777cd59f-64c5-49a7-94e8-fe78de57f708

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

The PR unifies the release workflow by removing release logic from main.yml, introducing a new tag-based release.yml workflow that handles Android builds, versioning, changelog generation, and GitHub release creation, while removing tag-push triggers from desktop.yml.

Changes

Cohort / File(s) Summary
Desktop Workflow Trigger Simplification
.github/workflows/desktop.yml
Removed the push trigger for tag-based workflows (push: tags: ['v*.*.*']), leaving only workflow_dispatch as the manual trigger; automated tag-based invocation now happens via repository_dispatch from the new release workflow.
Main Workflow Refactored to CI-Only
.github/workflows/main.yml
Workflow renamed from "Build" to "Build Check" and repurposed as a minimal CI check; removed all release-oriented steps (signing, keystore setup, dependency management, version extraction, artifact uploads, release creation, and desktop build dispatch); checkout upgraded v3→v4, Java setup upgraded v3.12.0→v4; final pipeline now builds debug APK only.
New Unified Tag-Based Release Workflow
.github/workflows/release.yml
Complete new Android release workflow triggered by tag pushes matching v*; orchestrates version extraction from tag, changelog generation from commits, pubspec version bump, Android/Flutter/keystore setup, APK/AAB builds and signing, GitHub Release creation with artifacts, desktop build dispatch via repository_dispatch, and keystore cleanup.

Sequence Diagram(s)

sequenceDiagram
    participant Git as Git Repository
    participant GH as GitHub Actions
    participant Build as Flutter Builder
    participant Sign as APK/AAB Signer
    participant Release as GitHub Release API
    participant Desktop as Desktop Workflow
    
    Git->>GH: Tag push (v1.2.1)
    activate GH
    GH->>Git: Extract version from tag
    GH->>Git: Parse commits for changelog
    GH->>Git: Bump pubspec.yaml version
    GH->>Git: Commit & push to main
    deactivate GH
    
    activate GH
    GH->>Build: Setup Flutter & Android
    Build->>Build: flutter build apk --split-per-abi
    Build->>Build: flutter build appbundle
    GH->>Sign: Verify APK/AAB signatures
    Sign->>GH: Signing verified
    deactivate GH
    
    activate GH
    GH->>Release: Create GitHub Release
    Release->>Release: Attach APKs, AAB, release notes
    deactivate GH
    
    activate GH
    GH->>Desktop: Trigger desktop builds (repository_dispatch)
    Desktop->>Desktop: Build Linux/macOS/Windows
    deactivate GH
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • fix: desktop build fixes #350: Introduced repository_dispatch orchestration for triggering desktop builds from other workflows, which the new release.yml now leverages to dispatch desktop builds in response to tag pushes.
  • Creation of desktop application for windows and mac #340: Removed tag-push trigger from desktop.yml, aligning with this PR's architectural shift to tag-based release orchestration through the new unified release workflow.
  • GitHub Actions workflow simplified #275: Refactored main.yml to simplify and narrow CI logic to Android-focused builds, establishing the pattern of removing release logic that this PR completes.

Poem

🐰 A tag, a hop, and away we go,
No more steps in the release show,
One git push --tags sets it all in motion,
Version bumps and changelogs by devotion,
Desktop joins the dance with dispatch's potion! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'refactor: unify release workflow to tag-based trigger' directly and clearly summarizes the main change: consolidating the release process into a single tag-based workflow.
Linked Issues check ✅ Passed All coding objectives from issue #520 are met: new release.yml implements tag-based triggering with version extraction, changelog generation, pubspec.yaml updates, signing setup, APK/AAB building, GitHub Release creation, and desktop build triggers; main.yml is simplified to CI-only; desktop.yml is updated to remove direct tag trigger.
Out of Scope Changes check ✅ Passed All changes align with issue #520 requirements: release.yml (new unified workflow), main.yml (repurposed as CI-only), and desktop.yml (updated trigger mechanism) are all scope-appropriate modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/unified-release-workflow-520

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
.github/workflows/release.yml (1)

159-163: Consider adding flutter analyze and flutter test before release builds.

While the assumption is that code was validated before the tag was created, adding these checks here provides a final safety gate before publishing artifacts. This prevents releasing broken builds if someone tags an unvalidated commit.

Suggested addition after dependencies
       - name: Generate localization and other required files
         run: dart run build_runner build -d
 
+      - name: Analyze code
+        run: flutter analyze
+
+      - name: Run tests
+        run: flutter test
+
       - name: Update version in pubspec for build
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release.yml around lines 159 - 163, Add two CI steps after
the "Install dependencies" step to run static analysis and unit tests: add a
step named "Analyze" that runs "flutter analyze" and a step named "Run tests"
that runs "flutter test" (optionally with --coverage or --no-test-assets as
needed). Ensure these steps are placed before the "Generate localization and
other required files" step so the workflow stops the release if analysis or
tests fail.
.github/workflows/main.yml (1)

42-49: Consider adding flutter analyze and flutter test to the CI check.

This workflow runs on every push to main but only performs a debug build. Per coding guidelines, flutter analyze and flutter test are mandatory before commits. Adding these steps would catch lint issues and test regressions early, strengthening the CI gate.

Suggested additions before the build step
       - name: Generate localization and other required files
         run: dart run build_runner build -d
 
+      - name: Analyze code
+        run: flutter analyze
+
+      - name: Run tests
+        run: flutter test
+
       - name: Build APK (debug check)
         run: flutter build apk --debug

Based on learnings: "Always run flutter analyze after any code change - it is mandatory before commits" and "Always run flutter test after any code change - it is mandatory before commits."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/main.yml around lines 42 - 49, Add CI steps to run static
analysis and unit/widget tests before the build step: insert two steps named
"Run flutter analyze" (command: flutter analyze) and "Run flutter test"
(command: flutter test --no-sound-null-safety or as appropriate) prior to the
"Build APK (debug check)" step so the workflow fails on lint or test failures;
reference the existing step names "Install Dependencies", "Generate localization
and other required files", and "Build APK (debug check)" to position the new
steps in the correct order and ensure they run after dependencies are installed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/release.yml:
- Around line 101-110: The workflow currently runs the sed version update while
on the tag and then runs git checkout main and git merge --ff-only with a
trailing "|| true", which can overwrite or lose the pubspec.yaml change and
silently ignore merge failures; modify the "Commit version bump to main" step so
that you first fetch and checkout main (git fetch origin main; git checkout
main), then perform the sed update of pubspec.yaml (apply the version bump)
while on main, remove the "|| true" from git merge --ff-only ${{
steps.version.outputs.full_tag }} so the job fails if fast-forward merge is not
possible (or replace with an explicit rebase/merge strategy), then git add
pubspec.yaml, git diff --cached --quiet || git commit -m "chore: update version
for ${{ steps.version.outputs.full_tag }}", and git push origin main to ensure
the bump is applied on main and merge problems are surfaced.

---

Nitpick comments:
In @.github/workflows/main.yml:
- Around line 42-49: Add CI steps to run static analysis and unit/widget tests
before the build step: insert two steps named "Run flutter analyze" (command:
flutter analyze) and "Run flutter test" (command: flutter test
--no-sound-null-safety or as appropriate) prior to the "Build APK (debug check)"
step so the workflow fails on lint or test failures; reference the existing step
names "Install Dependencies", "Generate localization and other required files",
and "Build APK (debug check)" to position the new steps in the correct order and
ensure they run after dependencies are installed.

In @.github/workflows/release.yml:
- Around line 159-163: Add two CI steps after the "Install dependencies" step to
run static analysis and unit tests: add a step named "Analyze" that runs
"flutter analyze" and a step named "Run tests" that runs "flutter test"
(optionally with --coverage or --no-test-assets as needed). Ensure these steps
are placed before the "Generate localization and other required files" step so
the workflow stops the release if analysis or tests fail.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5cc8fdc3-4a7d-45b6-a00b-a0f2380597d1

📥 Commits

Reviewing files that changed from the base of the PR and between 12eaee4 and d0d2565.

📒 Files selected for processing (3)
  • .github/workflows/desktop.yml
  • .github/workflows/main.yml
  • .github/workflows/release.yml
💤 Files with no reviewable changes (1)
  • .github/workflows/desktop.yml

Comment on lines +101 to +110
- name: Commit version bump to main
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git fetch origin main
git checkout main
git merge --ff-only ${{ steps.version.outputs.full_tag }} || true
git add pubspec.yaml
git diff --cached --quiet || git commit -m "chore: update version for ${{ steps.version.outputs.full_tag }}"
git push origin main

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Potential issue: version bump may be lost due to checkout sequencing.

The sed command updates pubspec.yaml while checked out at the tag (lines 94-99). Then git checkout main (line 106) may overwrite the working tree, potentially losing the sed changes if the pubspec differs between the tag and main.

Additionally, || true on the merge (line 107) silently swallows failures—if main has diverged and fast-forward isn't possible, the workflow continues without properly merging, which could leave pubspec.yaml in an inconsistent state.

Suggested fix: restructure to apply version bump after checkout
       - name: Commit version bump to main
         run: |
           git config user.name "github-actions[bot]"
           git config user.email "github-actions[bot]@users.noreply.github.com"
           git fetch origin main
           git checkout main
-          git merge --ff-only ${{ steps.version.outputs.full_tag }} || true
+          git merge --ff-only ${{ steps.version.outputs.full_tag }}
+
+          # Apply version bump after checkout
+          VERSION=${{ steps.version.outputs.tag }}
+          BUILD=$(git rev-list --count HEAD)
+          sed -i "s/^version: .*/version: ${VERSION}+${BUILD}/" pubspec.yaml
+
           git add pubspec.yaml
           git diff --cached --quiet || git commit -m "chore: update version for ${{ steps.version.outputs.full_tag }}"
           git push origin main

This ensures the version bump is applied after checking out main, and removes the silent failure on merge. If you want to handle diverged branches gracefully, consider a rebase or explicit error handling.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Commit version bump to main
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git fetch origin main
git checkout main
git merge --ff-only ${{ steps.version.outputs.full_tag }} || true
git add pubspec.yaml
git diff --cached --quiet || git commit -m "chore: update version for ${{ steps.version.outputs.full_tag }}"
git push origin main
- name: Commit version bump to main
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git fetch origin main
git checkout main
git merge --ff-only ${{ steps.version.outputs.full_tag }}
# Apply version bump after checkout
VERSION=${{ steps.version.outputs.tag }}
BUILD=$(git rev-list --count HEAD)
sed -i "s/^version: .*/version: ${VERSION}+${BUILD}/" pubspec.yaml
git add pubspec.yaml
git diff --cached --quiet || git commit -m "chore: update version for ${{ steps.version.outputs.full_tag }}"
git push origin main
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release.yml around lines 101 - 110, The workflow currently
runs the sed version update while on the tag and then runs git checkout main and
git merge --ff-only with a trailing "|| true", which can overwrite or lose the
pubspec.yaml change and silently ignore merge failures; modify the "Commit
version bump to main" step so that you first fetch and checkout main (git fetch
origin main; git checkout main), then perform the sed update of pubspec.yaml
(apply the version bump) while on main, remove the "|| true" from git merge
--ff-only ${{ steps.version.outputs.full_tag }} so the job fails if fast-forward
merge is not possible (or replace with an explicit rebase/merge strategy), then
git add pubspec.yaml, git diff --cached --quiet || git commit -m "chore: update
version for ${{ steps.version.outputs.full_tag }}", and git push origin main to
ensure the bump is applied on main and merge problems are surfaced.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Fixed in f3f9566 — version bump now happens after git checkout main, and removed || true from the merge so diverged branches fail fast instead of silently continuing.

MostronatorCoder[bot] added 2 commits March 9, 2026 17:54
- Move sed version update to after git checkout main (prevents overwrite)
- Remove || true from ff-only merge (fail fast on diverged branches)
- Consolidate version bump into the commit step
- main.yml: run flutter analyze + flutter test before debug build
- release.yml: run flutter analyze + flutter test after code gen, before APK build
- Ensures releases and CI builds fail on lint/test issues

@grunch grunch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@grunch grunch merged commit e6e5c22 into main Mar 9, 2026
2 checks passed
@grunch grunch deleted the refactor/unified-release-workflow-520 branch March 9, 2026 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: unify release workflow to tag-based trigger

1 participant