Skip to content

feat(web): GA4 + Search Console and a free browser tools hub (#5) #14

feat(web): GA4 + Search Console and a free browser tools hub (#5)

feat(web): GA4 + Search Console and a free browser tools hub (#5) #14

Workflow file for this run

name: Release
on:
push:
branches:
- main
# Website-only changes never need a desktop release/packaging run.
# (release-please also has exclude-paths: ["apps/web"] as a safety net.)
paths-ignore:
- 'apps/web/**'
workflow_dispatch:
inputs:
tag:
description: 'Existing release tag to (re)build and upload assets for (e.g. v0.2.0). Leave empty to run release-please.'
required: false
type: string
permissions:
contents: write
issues: write
pull-requests: write
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
env:
NODE_VERSION: 22
jobs:
release-please:
name: Release Please
if: ${{ inputs.tag == '' || inputs.tag == null }}
runs-on: ubuntu-latest
outputs:
release_created: ${{ steps.release.outputs.release_created }}
tag_name: ${{ steps.release.outputs.tag_name }}
version: ${{ steps.release.outputs.version }}
steps:
- name: Run release-please
id: release
uses: googleapis/release-please-action@v4
with:
token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
config-file: release-please-config.json
manifest-file: .release-please-manifest.json
build:
name: Build ${{ matrix.name }}
needs: release-please
if: |
always() && !cancelled() &&
(needs.release-please.outputs.release_created == 'true' || inputs.tag != '')
runs-on: ${{ matrix.runner }}
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- name: macOS arm64
runner: macos-26
builder_target: --mac --arm64
artifact_name: openbroca-macos-arm64
- name: macOS x64
runner: macos-26-intel
builder_target: --mac --x64
artifact_name: openbroca-macos-x64
- name: Windows x64
runner: windows-latest
builder_target: --win --x64
artifact_name: openbroca-windows-x64
steps:
- name: Checkout release tag
uses: actions/checkout@v4
with:
ref: ${{ inputs.tag != '' && inputs.tag || needs.release-please.outputs.tag_name }}
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build desktop app
run: pnpm --filter openbroca-desktop build
- name: Package installer
env:
# Only feed mac signing creds to macOS runners; Windows uses no
# codesign cert here, so leaving CSC_LINK empty prevents
# electron-builder from trying to sign the exe with the mac p12.
CSC_LINK: ${{ startsWith(matrix.runner, 'macos') && secrets.MAC_CSC_LINK || '' }}
CSC_KEY_PASSWORD: ${{ startsWith(matrix.runner, 'macos') && secrets.MAC_CSC_KEY_PASSWORD || '' }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: pnpm --filter openbroca-desktop exec electron-builder ${{ matrix.builder_target }} --publish never
- name: Collect release assets
shell: bash
run: |
mkdir -p release-assets
find apps/desktop/dist -maxdepth 1 -type f \
\( -name '*.dmg' -o -name '*.zip' -o -name '*.exe' -o -name '*.blockmap' -o -name 'latest*.yml' \) \
-print -exec cp {} release-assets/ \;
if [[ -z "$(find release-assets -type f -print -quit)" ]]; then
echo "No release assets were produced."
find apps/desktop/dist -maxdepth 2 -print
exit 1
fi
find release-assets -maxdepth 1 -type f -print | sort
- name: Upload installer artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact_name }}
path: release-assets/*
if-no-files-found: error
retention-days: 14
upload-assets:
name: Upload installers to GitHub Release
needs:
- release-please
- build
if: |
always() && !cancelled() && needs.build.result == 'success'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download installer artifacts
uses: actions/download-artifact@v4
with:
path: artifacts-raw
- name: Assemble release assets
shell: bash
run: |
set -euo pipefail
mkdir -p release-assets
# Flatten binaries and blockmaps from every per-runner artifact.
find artifacts-raw -type f \
\( -name '*.dmg' -o -name '*.zip' -o -name '*.exe' -o -name '*.blockmap' \) \
-exec cp {} release-assets/ \;
# Windows/Linux manifests are single-arch, copy as-is.
find artifacts-raw -type f \
\( -name 'latest.yml' -o -name 'latest-linux.yml' \) \
-exec cp {} release-assets/ \;
# macOS ships arm64 + x64 from two runners; their latest-mac.yml
# files each list only their own arch. Merge the `files:` arrays
# so electron-updater can find a match for either architecture.
mac_yml_count=$(find artifacts-raw -type f -name 'latest-mac.yml' | wc -l | tr -d ' ')
if [[ "$mac_yml_count" -gt 1 ]]; then
python3 -m pip install --quiet pyyaml
python3 <<'PY'
import pathlib, yaml
paths = sorted(pathlib.Path('artifacts-raw').rglob('latest-mac.yml'))
docs = [yaml.safe_load(p.read_text()) for p in paths]
merged = dict(docs[0])
seen, files = set(), []
for d in docs:
for f in d.get('files', []) or []:
url = f.get('url')
if url and url not in seen:
seen.add(url)
files.append(f)
merged['files'] = files
pathlib.Path('release-assets/latest-mac.yml').write_text(
yaml.safe_dump(merged, sort_keys=False, default_flow_style=False)
)
PY
else
find artifacts-raw -type f -name 'latest-mac.yml' -exec cp {} release-assets/ \;
fi
find release-assets -maxdepth 1 -type f -print | sort
- name: Upload release assets
shell: bash
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
RELEASE_TAG: ${{ inputs.tag != '' && inputs.tag || needs.release-please.outputs.tag_name }}
run: |
gh release upload "${RELEASE_TAG}" release-assets/* --clobber