Release (stable) #4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Release version (e.g. 0.2.0, 1.0.0)" | |
| required: true | |
| type: string | |
| dry_run: | |
| description: "Dry run — skip tag push and build (for testing)" | |
| required: false | |
| type: boolean | |
| default: false | |
| permissions: | |
| contents: write | |
| jobs: | |
| # ── Step 1: Bump version, commit, tag, push ────────────────────── | |
| prepare: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| tag: v${{ inputs.version }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: "24" | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v6 | |
| - name: Validate version format | |
| run: | | |
| if ! echo "${{ inputs.version }}" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$'; then | |
| echo "::error::Invalid version format. Use semver like 0.2.0 or 1.0.0-beta.1" | |
| exit 1 | |
| fi | |
| if git rev-parse "v${{ inputs.version }}" >/dev/null 2>&1; then | |
| echo "::error::Tag v${{ inputs.version }} already exists" | |
| exit 1 | |
| fi | |
| - name: Bump version in package.json | |
| run: | | |
| node -e " | |
| const fs = require('fs'); | |
| const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); | |
| pkg.version = '${{ inputs.version }}'; | |
| fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n'); | |
| " | |
| - name: Commit and tag | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git add package.json | |
| if git diff --cached --quiet; then | |
| echo "package.json already at v${{ inputs.version }}; skipping bump commit." | |
| else | |
| git commit -m "release: v${{ inputs.version }}" | |
| fi | |
| git tag "v${{ inputs.version }}" | |
| - name: Push commit and tag | |
| if: ${{ !inputs.dry_run }} | |
| run: | | |
| git push origin HEAD | |
| git push origin "v${{ inputs.version }}" | |
| # ── Step 2: Build installers for each platform ─────────────────── | |
| build: | |
| needs: prepare | |
| if: ${{ !inputs.dry_run }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: windows-latest | |
| artifact: dist-windows | |
| - os: ubuntu-latest | |
| artifact: dist-linux | |
| - os: macos-latest | |
| artifact: dist-mac | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Checkout tag | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ needs.prepare.outputs.tag }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: "24" | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v6 | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build app | |
| run: pnpm run build | |
| shell: bash | |
| env: | |
| SENTRY_DSN: ${{ vars.SENTRY_DSN }} | |
| SENTRY_ENVIRONMENT: ${{ vars.SENTRY_ENVIRONMENT || 'production' }} | |
| POSTHOG_ENABLED: ${{ vars.POSTHOG_ENABLED || '1' }} | |
| POSTHOG_KEY: ${{ vars.POSTHOG_KEY }} | |
| POSTHOG_HOST: ${{ vars.POSTHOG_HOST || 'https://us.i.posthog.com' }} | |
| POSTHOG_ENABLE_DEV: "0" | |
| - name: Upload Sentry source maps | |
| if: matrix.os == 'ubuntu-latest' | |
| run: | | |
| # Local `pnpm run dist` cleans source maps before packaging. Release CI | |
| # uploads them from the build output first, then removes them below. | |
| if [ -z "$SENTRY_AUTH_TOKEN" ] || [ -z "$SENTRY_ORG" ] || [ -z "$SENTRY_PROJECT" ]; then | |
| echo "Sentry secrets are not configured; skipping source map upload." | |
| exit 0 | |
| fi | |
| pnpm run sentry:sourcemaps | |
| shell: bash | |
| env: | |
| SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} | |
| SENTRY_ORG: ${{ vars.SENTRY_ORG }} | |
| SENTRY_PROJECT: ${{ vars.SENTRY_PROJECT }} | |
| - name: Remove packaged source maps | |
| run: pnpm run clean:sourcemaps | |
| shell: bash | |
| - name: Package | |
| run: | | |
| if [ "${{ matrix.os }}" = "windows-latest" ]; then | |
| pnpm run prepare:package-assets | |
| pnpm exec electron-builder --win | |
| else | |
| if [ "${{ matrix.os }}" = "macos-latest" ]; then | |
| pnpm run prepare:agent-plugins | |
| pnpm exec electron-builder --mac | |
| else | |
| pnpm run prepare:package-assets | |
| pnpm exec electron-builder --linux | |
| fi | |
| fi | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Upload built artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: ${{ matrix.artifact }} | |
| path: | | |
| release/Lightcode-*.exe | |
| release/Lightcode-*.dmg | |
| release/Lightcode-*.AppImage | |
| release/Lightcode-*.deb | |
| release/latest*.yml | |
| release/*.blockmap | |
| if-no-files-found: error | |
| retention-days: 7 | |
| # ── Step 3: Create GitHub Release with auto-generated notes ────── | |
| release: | |
| needs: [prepare, build] | |
| if: ${{ !inputs.dry_run }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Download all build artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: release-assets | |
| pattern: dist-* | |
| merge-multiple: true | |
| - name: List release assets | |
| run: ls -lh release-assets | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ needs.prepare.outputs.tag }} | |
| name: Lightcode ${{ needs.prepare.outputs.tag }} | |
| generate_release_notes: true | |
| fail_on_unmatched_files: true | |
| files: release-assets/* | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # ── Step 4: Bump master to next dev version ──────────────────────── | |
| post-release: | |
| needs: [prepare, release] | |
| if: ${{ !inputs.dry_run }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout master | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: master | |
| fetch-depth: 1 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: "24" | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v6 | |
| - name: Bump to next patch-dev version | |
| run: | | |
| node -e " | |
| const fs = require('fs'); | |
| const p = JSON.parse(fs.readFileSync('package.json', 'utf8')); | |
| const v = p.version.split('.').map(Number); | |
| p.version = v[0] + '.' + v[1] + '.' + (v[2] + 1) + '-dev'; | |
| fs.writeFileSync('package.json', JSON.stringify(p, null, 2) + '\n'); | |
| " | |
| - name: Commit and push | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git add package.json | |
| git commit -m "chore: bump to next dev version" | |
| git push |