Skip to content

Commit 2e82736

Browse files
Add versioning (#452)
* feat: add version environment variables and configuration - Add version-related environment variable types - Extend config.ts to include version information with fallback values - Add build-time version injection - Include version variables in test environment configuration * feat: enhance semantic-release configuration for staging/production workflow - Update semantic-release to support staging (beta) and production (stable) branches - Add enhanced release notes proper categorization - Configure changelog generation and git commits for version management - Add commitlint configuration for conventional commit validation - Add semantic-release plugins: changelog, git, and enhanced GitHub integration - Maintain npm plugin for package.json version updates (without publishing) * feat: create unified version management system - Add useVersion hook that works for both web and desktop platforms - Create VersionDisplay component with environment badges and optional details - Support Tauri desktop version detection while falling back to web config - Include build date, commit hash, and environment information * feat: update settings page with enhanced version display and comprehensive tests - Replace legacy Tauri-specific version display with unified VersionDisplay component - Add error handling to useVersion hook * feat: add version synchronization script for web and desktop builds - Create sync-version.cjs script to sync versions from package.json to Cargo.toml - Add standalone npm run sync-version command and tntegrated version sync into build process * feat: create staging deployment workflow for automated beta releases - Add GitHub Actions workflow that triggers on staging branch pushes * feat: update production release workflow and add promotion workflow - Create new promote-to-production.yml workflow for manual staging→main merges - Enhance release-web.yaml with version injection and bot token authentication - Remove staging deployment from production workflow for better separation - Use bot token (engineering-ci[bot]) for all git operations across workflows * feat: update desktop release workflow integration - Add proper bot token generation using GitHub App credentials (BOT_ID + BOT_SK) - Integrate version synchronization with npm run sync-version to keep Cargo.toml in sync - Ensure desktop releases use same versioning system as web releases * docs: add comprehensive versioning documentation * docs: add comprehensive versioning documentation * feat: update branching strategy to use main as staging and release as production BREAKING CHANGE: Branching strategy has changed. Production deployments now use 'release' branch, staging uses 'main' branch. New workflow: - Feature branches → main (staging environment, beta releases) - main → release (production environment, stable releases) - Changed production deployments to trigger on 'release' branch instead of 'main' - Updated staging deployments to trigger on 'main' branch instead of 'staging' - Modified promotion workflow to merge 'main' → 'release' instead of 'staging' → 'main' - Updated semantic-release configuration to create stable releases from 'release' branch and beta releases from 'main' * docs: add workflow descriptions and update release process documentation - Added detailed descriptions to all GitHub Actions workflow files explaining their role - Updated README.md release process section with workflow file names for each step - Clarified staging deployment uses Cloudflare Pages and desktop releases are manual All workflows now clearly document when they trigger, what they do, and their role in the release process. * refactor: removed version env vars * chore(config): convert semantic-release to TypeScript and optimize configuration * feat(ci): implement orchestrator release workflow for unified web and desktop releases • Add orchestrator pattern to coordinate web and desktop releases from single workflow • Create reusable release-desktop.yaml workflow for cross-platform desktop builds • Implement efficient build strategy: build frontend once, reuse across all platforms • Fix semantic-release to upload web artifacts to GitHub releases • Simplify environment configuration with direct production values • Add tauri:build convenience script and remove beforeBuildCommand from tauri.conf.json * chore(docs): moved release info to CONTRIBUTING.md * test: consolidate settings tests at page level * chore: adjust the build layout and apply some fixes * refactor(ci): combine build-app and create-release into single job - Eliminate duplicate Node.js setup and npm install steps - Combine build-app and create-release into build-and-release job - Optimize workflow execution flow: version → sync → commit → build - Update job dependencies to use single upstream job refactor: rename create-release action to generate-release-version * feat: use branch name instead of semantic-release output for production release detection - Add IS_PRODUCTION_RELEASE environment variable for consistency - Replace release-published checks with github.ref_name == 'release' * fix: updated release.yml * fix: handle breaking changes and cleaned main git history * chore(ci): removed dependency on release web for sync to main * chore: removed unused workflow output * chore: uncommented used code * refactor: removed keywords parseOpts * docs: updated contributing guide * refactor: release config ts to conditionally update changelog only on release branch --------- Co-authored-by: Neil Campbell <[email protected]>
1 parent 7235e66 commit 2e82736

29 files changed

+3684
-1328
lines changed

.commitlintrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extends": ["@commitlint/config-conventional"],
3+
"rules": {
4+
"type-enum": [2, "always", ["feat", "fix", "docs", "style", "refactor", "perf", "test", "build", "ci", "chore", "revert"]],
5+
"subject-empty": [2, "never"],
6+
"subject-full-stop": [2, "never", "."],
7+
"header-max-length": [2, "always", 100]
8+
}
9+
}

.github/actions/build-linux/action.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ runs:
5959
- name: Setup tauri.conf.json
6060
if: ${{ inputs.release-version != '' }}
6161
run: |
62-
sed -i "s/\"version\": \"0.1.0\"/\"version\": \"${{ inputs.release-version }}\"/g" "src-tauri/tauri.conf.json"
62+
sed -i "s/\"version\": \"0.0.0\"/\"version\": \"${{ inputs.release-version }}\"/g" "src-tauri/tauri.conf.json"
6363
sed -i "s/\"createUpdaterArtifacts\": false/\"createUpdaterArtifacts\": true/g" "src-tauri/tauri.conf.json"
6464
sed -i "s/CN_ORG_NAME/${{ inputs.crabnebula-org-name }}/g" "src-tauri/tauri.conf.json"
6565
sed -i "s/CN_APP_NAME/${{ inputs.crabnebula-app-name }}/g" "src-tauri/tauri.conf.json"

.github/actions/build-mac/action.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ runs:
8080
- name: Setup tauri.conf.json
8181
if: ${{ inputs.release-version != '' }}
8282
run: |
83-
sed -i '' "s/\"version\": \"0.1.0\"/\"version\": \"${{ inputs.release-version }}\"/g" "src-tauri/tauri.conf.json"
83+
sed -i '' "s/\"version\": \"0.0.0\"/\"version\": \"${{ inputs.release-version }}\"/g" "src-tauri/tauri.conf.json"
8484
sed -i '' "s/\"createUpdaterArtifacts\": false/\"createUpdaterArtifacts\": true/g" "src-tauri/tauri.conf.json"
8585
sed -i '' "s/CN_ORG_NAME/${{ inputs.crabnebula-org-name }}/g" "src-tauri/tauri.conf.json"
8686
sed -i '' "s/CN_APP_NAME/${{ inputs.crabnebula-app-name }}/g" "src-tauri/tauri.conf.json"

.github/actions/build-windows/action.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ runs:
4949
run: |
5050
input_version="${{ inputs.release-version }}"
5151
version="${input_version/beta./""}"
52-
sed -i "s/\"version\": \"0.1.0\"/\"version\": \"$version\"/g" "src-tauri/tauri.conf.json"
52+
sed -i "s/\"version\": \"0.0.0\"/\"version\": \"$version\"/g" "src-tauri/tauri.conf.json"
5353
sed -i "s/\"createUpdaterArtifacts\": false/\"createUpdaterArtifacts\": true/g" "src-tauri/tauri.conf.json"
5454
sed -i "s/CN_ORG_NAME/${{ inputs.crabnebula-org-name }}/g" "src-tauri/tauri.conf.json"
5555
sed -i "s/CN_APP_NAME/${{ inputs.crabnebula-app-name }}/g" "src-tauri/tauri.conf.json"

.github/actions/create-release/action.yaml renamed to .github/actions/generate-release-version/action.yaml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ inputs:
44
github-token:
55
description: 'The GitHub token'
66
required: true
7-
production-release:
8-
description: 'Is production release?'
9-
required: true
107
node-version:
118
description: 'The Node version'
129
required: true
@@ -32,22 +29,31 @@ runs:
3229
uses: actions/setup-node@v4
3330
with:
3431
node-version: ${{ inputs.node-version }}
32+
registry-url: 'https://npm.pkg.github.com'
33+
scope: '@algorandfoundation'
34+
cache: 'npm'
3535

3636
- name: Install npm dependencies
37-
run: npm install
37+
run: npm ci --ignore-scripts
38+
env:
39+
NODE_AUTH_TOKEN: ${{ inputs.github-token }}
40+
shell: bash
41+
42+
# Let scripts run without the token
43+
- run: npm rebuild
3844
shell: bash
3945

4046
- name: Get next version (dry run)
4147
id: get-next-version
42-
run: npx semantic-release --dry-run ${{ inputs.production-release == 'true' && '--branches main' || '' }}
48+
run: npx semantic-release --dry-run
4349
env:
4450
GITHUB_TOKEN: ${{ inputs.github-token }}
4551
shell: bash
4652

47-
- name: Create release ${{ inputs.production-release == 'true' && '' || 'beta' }}
53+
- name: Create release
4854
env:
4955
GITHUB_TOKEN: ${{ inputs.github-token }}
50-
run: npx semantic-release ${{ inputs.production-release == 'true' && '--branches main' || '' }}
56+
run: npx semantic-release
5157
shell: bash
5258

5359
- name: Get release tag

.github/workflows/pr.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ name: PR checks
22

33
on:
44
pull_request:
5-
branches: '**'
65

76
permissions: {}
87

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Promotion Workflow
2+
#
3+
# This workflow is manually triggered to promote tested changes from 'main' to 'release'.
4+
# It performs a merge from main branch to release branch, which then triggers
5+
# the production deployment workflow.
6+
#
7+
# Role in release workflow:
8+
# - Manually triggered via GitHub Actions UI
9+
# - Merges tested changes from 'main' → 'release' branch
10+
# - Triggers production deployment automatically after merge
11+
# - Acts as the final approval gate before production release
12+
13+
name: Promote to Production
14+
15+
on:
16+
workflow_dispatch:
17+
inputs:
18+
promote-from-main:
19+
description: 'Promote main to production'
20+
required: true
21+
default: true
22+
type: boolean
23+
24+
concurrency: promote-to-production
25+
26+
jobs:
27+
promote-main-to-release:
28+
name: Promote Main to Release
29+
runs-on: ubuntu-latest
30+
if: inputs.promote-from-main
31+
steps:
32+
- name: Generate bot token
33+
uses: actions/create-github-app-token@v1
34+
id: app_token
35+
with:
36+
app-id: ${{ secrets.BOT_ID }}
37+
private-key: ${{ secrets.BOT_SK }}
38+
39+
- uses: actions/checkout@v4
40+
with:
41+
fetch-depth: 0
42+
token: ${{ steps.app_token.outputs.token }}
43+
44+
- name: Set Git user as GitHub actions
45+
run: git config --global user.email "179917785+engineering-ci[bot]@users.noreply.github.com" && git config --global user.name "engineering-ci[bot]"
46+
47+
- name: Merge main to release
48+
id: merge-main
49+
run: |
50+
git checkout release
51+
git pull origin release
52+
git merge origin/main --no-ff -X theirs -m "chore: promote main (i.e. staging) to production
53+
54+
This promotion merges tested changes from main branch to release for production release."
55+
git push origin release
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
# Desktop Release Workflow
2+
#
3+
# This workflow is called by the main release orchestrator to build desktop applications.
4+
# It downloads pre-built web artifacts and builds cross-platform desktop applications.
5+
#
6+
# Role in release workflow:
7+
# - Called by main release.yaml orchestrator
8+
# - Receives version from semantic-release
9+
# - Downloads pre-built web artifacts
10+
# - Builds cross-platform desktop applications
11+
# - Publishes desktop apps via CrabNebula
12+
13+
name: Release Desktop
14+
15+
on:
16+
workflow_call:
17+
inputs:
18+
version:
19+
description: 'Release version'
20+
required: true
21+
type: string
22+
production-release:
23+
description: 'Production release?'
24+
required: true
25+
type: string
26+
release-tag:
27+
description: 'Release tag'
28+
required: true
29+
type: string
30+
crabnebula-release-id:
31+
description: 'CrabNebula release ID'
32+
required: true
33+
type: string
34+
35+
concurrency: build-desktop
36+
37+
env:
38+
PRODUCTION_RELEASE: ${{ inputs.production-release == 'true' }}
39+
40+
jobs:
41+
build-tauri:
42+
name: Build Tauri app
43+
runs-on: ${{ matrix.platform }}
44+
strategy:
45+
matrix:
46+
# macos-14 is the Apple Arm runner
47+
# macos-13 is the Apple Intel runner
48+
platform: [ubuntu-22.04, windows-latest, macos-13, macos-14]
49+
50+
steps:
51+
- name: Generate bot token
52+
uses: actions/create-github-app-token@v1
53+
id: app_token
54+
with:
55+
app-id: ${{ secrets.BOT_ID }}
56+
private-key: ${{ secrets.BOT_SK }}
57+
58+
- uses: actions/checkout@v4
59+
with:
60+
# Use bot token for authenticated operations
61+
token: ${{ steps.app_token.outputs.token }}
62+
fetch-depth: 0
63+
64+
- name: Setup node
65+
uses: actions/setup-node@v4
66+
with:
67+
node-version: 20
68+
registry-url: 'https://npm.pkg.github.com'
69+
scope: '@algorandfoundation'
70+
cache: 'npm'
71+
72+
- name: Install Rust stable
73+
uses: dtolnay/rust-toolchain@stable
74+
75+
- name: Install npm dependencies
76+
run: npm ci --ignore-scripts
77+
env:
78+
NODE_AUTH_TOKEN: ${{ steps.app_token.outputs.token }}
79+
80+
# Let scripts run without the token
81+
- run: npm rebuild
82+
83+
- name: Download app build artifacts
84+
uses: actions/download-artifact@v4
85+
with:
86+
name: app-build
87+
path: dist/
88+
89+
- name: Build for Linux
90+
id: build-linux
91+
if: ${{ runner.os == 'Linux' }}
92+
uses: ./.github/actions/build-linux
93+
with:
94+
release-tag: ${{ inputs.release-tag }}
95+
production-release: ${{ env.PRODUCTION_RELEASE }}
96+
crabnebula-release-id: ${{ inputs.crabnebula-release-id }}
97+
appimage-signing-private-key: ${{ secrets.APPIMAGE_SIGNING_PRIVATE_KEY }}
98+
appimage-signing-private-key-password: ${{ secrets.APPIMAGE_SIGNING_PRIVATE_KEY_PASSWORD }}
99+
tauri-signing-public-key: ${{ secrets.TAURI_SIGNING_PUBLIC_KEY }}
100+
tauri-signing-private-key: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
101+
tauri-signing-private-key-password: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
102+
crabnebula-org-name: ${{ secrets.CN_ORG_NAME }}
103+
crabnebula-app-name: ${{ secrets.CN_APP_NAME }}
104+
crabnebula-api-key: ${{ secrets.CN_API_KEY }}
105+
106+
- name: Build for Windows
107+
id: build-windows
108+
if: ${{ runner.os == 'Windows' }}
109+
uses: ./.github/actions/build-windows
110+
with:
111+
release-tag: ${{ inputs.release-tag }}
112+
production-release: ${{ env.PRODUCTION_RELEASE }}
113+
crabnebula-release-id: ${{ inputs.crabnebula-release-id }}
114+
package_name: algokit-lora
115+
azure_tenant_id: ${{ secrets.AZURE_TENANT_ID }}
116+
azure_client_id: ${{ secrets.AZURE_CLIENT_ID }}
117+
azure_client_secret: ${{ secrets.AZURE_CLIENT_SECRET }}
118+
tauri-signing-public-key: ${{ secrets.TAURI_SIGNING_PUBLIC_KEY }}
119+
tauri-signing-private-key: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
120+
tauri-signing-private-key-password: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
121+
crabnebula-org-name: ${{ secrets.CN_ORG_NAME }}
122+
crabnebula-app-name: ${{ secrets.CN_APP_NAME }}
123+
crabnebula-api-key: ${{ secrets.CN_API_KEY }}
124+
125+
- name: Build for Mac
126+
id: build-mac
127+
if: ${{ runner.os == 'macOS' }}
128+
uses: ./.github/actions/build-mac
129+
with:
130+
release-tag: ${{ inputs.release-tag }}
131+
production-release: ${{ env.PRODUCTION_RELEASE }}
132+
crabnebula-release-id: ${{ inputs.crabnebula-release-id }}
133+
apple-certificate: ${{ secrets.APPLE_CERTIFICATE }}
134+
apple-certificate-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
135+
keychain-password: ${{ secrets.KEYCHAIN_PASSWORD }}
136+
apple-id: ${{ secrets.APPLE_ID }}
137+
apple-password: ${{ secrets.APPLE_PASSWORD }}
138+
apple-team-id: ${{ secrets.APPLE_TEAM_ID }}
139+
tauri-signing-public-key: ${{ secrets.TAURI_SIGNING_PUBLIC_KEY }}
140+
tauri-signing-private-key: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
141+
tauri-signing-private-key-password: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
142+
crabnebula-org-name: ${{ secrets.CN_ORG_NAME }}
143+
crabnebula-app-name: ${{ secrets.CN_APP_NAME }}
144+
crabnebula-api-key: ${{ secrets.CN_API_KEY }}
145+
146+
publish-crabnebula:
147+
name: Publish CrabNebula release
148+
needs:
149+
- build-tauri
150+
runs-on: ubuntu-latest
151+
steps:
152+
- name: Publish CrabNebula release
153+
uses: crabnebula-dev/[email protected]
154+
with:
155+
command: release publish "${{ secrets.CN_ORG_NAME }}/${{ secrets.CN_APP_NAME }}" "${{ inputs.crabnebula-release-id }}" ${{ env.PRODUCTION_RELEASE != 'true' && '--channel beta' || '' }}
156+
api-key: ${{ secrets.CN_API_KEY }}

0 commit comments

Comments
 (0)