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
57 changes: 56 additions & 1 deletion .github/workflows/flatpak.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,38 @@ on:
tags: ['v*']

jobs:
schema-release-compare:
name: Schema vs last official release
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
schema_bumped: ${{ steps.compare.outputs.schema_bumped }}
curr_schema: ${{ steps.compare.outputs.curr_schema }}
prev_schema: ${{ steps.compare.outputs.prev_schema }}
prev_tag: ${{ steps.compare.outputs.prev_tag }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Compare schema to last published release
id: compare
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: >
node scripts/ci-schema-release-compare.mjs
--workflow-label "Build Flatpak"
--write-readme READ-ME-FIRST-flatpak.md

- name: Upload READ-ME-FIRST warning
uses: actions/upload-artifact@v7
with:
name: READ-ME-FIRST-flatpak
path: READ-ME-FIRST-flatpak.md
retention-days: 30

# Sidecar is built on bare Ubuntu runners (apt). The flathub-infra Flatpak container is a
# minimal freedesktopsdk/sdk rootfs with no apt/dnf — host cargo builds cannot install deps there.
reticulum-sidecar:
Expand Down Expand Up @@ -60,7 +92,7 @@ jobs:
# "Flatpak system operation Deploy not allowed for user".
flatpak:
name: Flatpak (${{ matrix.arch }})
needs: reticulum-sidecar
needs: [reticulum-sidecar, schema-release-compare]
runs-on: ${{ matrix.runner }}
permissions:
contents: read
Expand All @@ -84,6 +116,20 @@ jobs:
name: mesh-client-reticulum-${{ matrix.arch }}
path: resources/reticulum-sidecar

- name: Write schema upgrade installer notice
env:
MESH_CLIENT_SCHEMA_BUMPED: ${{ needs.schema-release-compare.outputs.schema_bumped }}
MESH_CLIENT_SCHEMA_CURR: ${{ needs.schema-release-compare.outputs.curr_schema }}
MESH_CLIENT_SCHEMA_PREV: ${{ needs.schema-release-compare.outputs.prev_schema }}
MESH_CLIENT_SCHEMA_PREV_TAG: ${{ needs.schema-release-compare.outputs.prev_tag }}
run: node scripts/write-schema-upgrade-notice.mjs

- name: Download READ-ME-FIRST warning
uses: actions/download-artifact@v8
with:
name: READ-ME-FIRST-flatpak
path: flatpak-warnings

- name: Generate offline pnpm sources
run: |
FBTOOLS=git+https://github.com/flatpak/flatpak-builder-tools
Expand Down Expand Up @@ -149,6 +195,15 @@ jobs:
exit 1
fi

# flatpak-builder already uploaded the .flatpak; attach the schema warning beside it
# for workflow_dispatch test builds (and tag runs) downloading Actions artifacts.
- name: Upload READ-ME-FIRST with Flatpak artifacts
uses: actions/upload-artifact@v7
with:
name: flatpak-schema-warning-${{ matrix.arch }}
path: flatpak-warnings/READ-ME-FIRST-flatpak.md
retention-days: 30

publish:
name: Publish to GitHub Release
needs: flatpak
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ resources/SCHEMA-UPGRADE.txt
resources/schema-upgrade-notice.nsh
READ-ME-FIRST-test-build.md
READ-ME-FIRST-schema.md
READ-ME-FIRST-flatpak.md

# Local runtime state (identities, path tables, caches) from running the sidecar
# directly (e.g. `pnpm run reticulum:sidecar:dev`) with no --reticulum-config-dir override
Expand Down
21 changes: 11 additions & 10 deletions docs/ci-cd.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Mesh-Client uses GitHub Actions for continuous integration and deployment.
| `build.yaml` | Manual `workflow_dispatch` | Native 3-OS packaging smoke build (+ schema compare vs last official) |
| `reticulum-sidecar.yaml` | Path-filtered push/PR to `main` | Sidecar fmt + Clippy (ubuntu); multi-OS matrix build/test |
| `release.yaml` | Version tags (`v*`) | Build & publish releases (AppImage/deb/rpm) |
| `flatpak.yaml` | Version tags (`v*`), manual | Build Flatpak; publish to release on tags |
| `flatpak.yaml` | Version tags (`v*`), manual | Build Flatpak (+ schema compare vs last official); publish to release on tags |
| `docs.yml` | Push to `main` | Deploy MkDocs to GitHub Pages |

---
Expand Down Expand Up @@ -117,13 +117,14 @@ See [Release Process](release-process.md) for the maintainer workflow.

Builds Flatpak bundles using [`flatpak/flatpak-github-actions`](https://github.com/flatpak/flatpak-github-actions).

**Triggers:** version tags (`v*`) and manual `workflow_dispatch`.
**Triggers:** version tags (`v*`) and manual `workflow_dispatch` (**Build Flatpak (no release)**).

A matrix builds **x86_64** and **aarch64** in parallel. Both use the same privileged `ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-24.08` container (Flathub remote, `flatpak-builder`, and system-scope runtime installs). **x86_64** runs on `ubuntu-latest`; **aarch64** runs on `ubuntu-24.04-arm` (native ARM runners — not QEMU on bare Ubuntu).

1. Generates `flatpak/generated-sources.json` via `flatpak-node-generator`
2. Builds from `org.coloradomesh.MeshClient.yml` with offline pnpm sources
3. Uploads `org.coloradomesh.MeshClient-{x86_64,aarch64}.flatpak` artifacts
1. **`schema-release-compare`** — same compare as Build Binaries / Release; uploads `READ-ME-FIRST-flatpak.md` and feeds `write-schema-upgrade-notice.mjs` so bumped schemas embed `SCHEMA-UPGRADE.txt` under Flatpak `resources/`
2. Builds the Reticulum sidecar on bare Ubuntu runners, then generates `flatpak/generated-sources.json` via `flatpak-node-generator`
3. Builds from `org.coloradomesh.MeshClient.yml` with offline pnpm sources
4. Uploads `org.coloradomesh.MeshClient-{x86_64,aarch64}.flatpak` artifacts plus per-arch `flatpak-schema-warning-*` (the READ-ME-FIRST note for Actions downloads)

On **version tag pushes**, a `publish` job attaches both bundles to the GitHub Release. aarch64 is the primary ARM Linux install path (release `build.yaml` only produces x86_64 AppImage/deb/rpm).

Expand Down Expand Up @@ -307,18 +308,18 @@ CI focuses on lint, typecheck, build, Flatpak metadata validation, and coverage

---

## Packaging smoke builds (`build.yaml` / `release.yaml`)
## Packaging smoke builds (`build.yaml` / `flatpak.yaml` / `release.yaml`)

### Schema compare vs last official release

Both workflows start with a **`schema-release-compare`** job (`scripts/ci-schema-release-compare.mjs`) that:
**Build Binaries**, **Build Flatpak**, and **Release** start with a **`schema-release-compare`** job (`scripts/ci-schema-release-compare.mjs`) that:

1. Labels **Build Binaries** runs as a **test build** (not an official release) in `$GITHUB_STEP_SUMMARY`
1. Labels **Build Binaries** / **Build Flatpak (no release)** runs as a **test build** (not an official release) in `$GITHUB_STEP_SUMMARY`
2. Compares this tree’s `CURRENT_SCHEMA_VERSION` to the last published (non-draft) GitHub Release tag
3. Uploads `READ-ME-FIRST-test-build.md` (build) / `READ-ME-FIRST-schema.md` (release) and includes the warning in platform artifact uploads when sharing Actions downloads
3. Uploads `READ-ME-FIRST-test-build.md` (build) / `READ-ME-FIRST-flatpak.md` (flatpak) / `READ-ME-FIRST-schema.md` (release) and includes the warning in platform / Flatpak artifact uploads when sharing Actions downloads
4. Exposes `schema_bumped` / `curr_schema` / `prev_schema` / `prev_tag` for packaging

When schema is bumped, packaging runs `scripts/write-schema-upgrade-notice.mjs` so Windows NSIS can show a MessageBox and macOS/Linux bundles can include `SCHEMA-UPGRADE.txt` via `electron-builder-before-pack.mjs`.
When schema is bumped, packaging runs `scripts/write-schema-upgrade-notice.mjs` so Windows NSIS can show a MessageBox and macOS/Linux/Flatpak bundles can include `SCHEMA-UPGRADE.txt` in app resources (`electron-builder-before-pack.mjs` / Flatpak `resources/` copy).

On first launch after a schema bump against an existing database, the app shows a blocking **Quit / Upgrade** dialog before mutating SQLite (see [Release Process — Database schema upgrades](release-process.md#database-schema-upgrades)).

Expand Down
11 changes: 6 additions & 5 deletions docs/release-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ Documentation deploys separately: [`docs.yml`](../.github/workflows/docs.yml) ru

`CURRENT_SCHEMA_VERSION` in [`src/main/db-schema-sync.ts`](../src/main/db-schema-sync.ts) is the on-disk SQLite `user_version` this build supports. Schema upgrades are **one-way**:

- **CI:** `schema-release-compare` (Build Binaries and Release) warns when this build’s schema is newer than the last published release. Test builds also upload `READ-ME-FIRST-test-build.md` with the artifact set.
- **Installers:** when bumped, Windows NSIS shows an advisory MessageBox; macOS/Linux packages may include `SCHEMA-UPGRADE.txt` in app resources.
- **CI:** `schema-release-compare` (Build Binaries, Build Flatpak, and Release) warns when this build’s schema is newer than the last published release. Test builds also upload a `READ-ME-FIRST-*.md` artifact with the download set.
- **Installers:** when bumped, Windows NSIS shows an advisory MessageBox; macOS/Linux/Flatpak packages may include `SCHEMA-UPGRADE.txt` in app resources.
- **App launch:** if an existing database’s `user_version` is behind this build, Mesh-Client shows a blocking **Quit / Upgrade** dialog **before** running `runSchemaUpgrade`. Quit leaves the database unchanged. Set `MESH_CLIENT_ACCEPT_SCHEMA_UPGRADE=1` to auto-accept (E2E / automation only).
- **Too new:** opening a database upgraded by a newer app with an older build still fails with the existing schema-too-new fatal dialog.

Expand Down Expand Up @@ -167,9 +167,10 @@ Build jobs also run `verify-reticulum-sidecar-staged.mjs` after staging sidecars

### `flatpak.yaml` (Build Flatpak)

1. **`reticulum-sidecar`** — builds `mesh-client-reticulum` per arch (x86_64 on `ubuntu-latest`, aarch64 on `ubuntu-24.04-arm`) with full RNS stack features
2. **`flatpak`** — generates offline pnpm sources, builds `org.coloradomesh.MeshClient.flatpak` per arch inside the Flathub freedesktop 24.08 container, smoke-installs the bundle
3. **`publish`** — attaches both `.flatpak` files to the GitHub Release with **`draft: true`** (does not auto-publish an existing draft)
1. **`schema-release-compare`** — compares this SHA’s schema to the last published release; uploads `READ-ME-FIRST-flatpak.md` (included again beside Flatpak Actions artifacts)
2. **`reticulum-sidecar`** — builds `mesh-client-reticulum` per arch (x86_64 on `ubuntu-latest`, aarch64 on `ubuntu-24.04-arm`) with full RNS stack features
3. **`flatpak`** — writes schema upgrade notice into `resources/` when bumped, generates offline pnpm sources, builds `org.coloradomesh.MeshClient.flatpak` per arch inside the Flathub freedesktop 24.08 container, smoke-installs the bundle
4. **`publish`** — attaches both `.flatpak` files to the GitHub Release with **`draft: true`** (does not auto-publish an existing draft)

Both tag-triggered workflows must complete before the release is fully populated. Flatpak bundles often arrive a few minutes after the Electron artifacts.

Expand Down
14 changes: 13 additions & 1 deletion scripts/ci-schema-release-compare.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,17 @@ export function readSchemaVersionFromFile(filePath) {
* prevSchema: number | null
* prevTag: string | null
* schemaBumped: boolean
* workflowLabel?: string
* }} opts
*/
export function formatSchemaCompareMarkdown(opts) {
const lines = [];
if (opts.mode === 'test-build') {
const workflowLabel = opts.workflowLabel?.trim() || 'Build Binaries';
lines.push('# Test build — not an official release');
lines.push('');
lines.push(
'These artifacts are from **Build Binaries** (`workflow_dispatch`). They are not a published GitHub Release.',
`These artifacts are from **${workflowLabel}** (\`workflow_dispatch\`). They are not a published GitHub Release.`,
);
lines.push('');
} else {
Expand Down Expand Up @@ -207,6 +209,15 @@ export async function runSchemaReleaseCompare(argv, env = process.env) {
? path.resolve(argv[readmeIdx + 1])
: path.join(ROOT, 'READ-ME-FIRST-test-build.md');

const labelIdx = argv.indexOf('--workflow-label');
const workflowLabel =
labelIdx >= 0 && argv[labelIdx + 1]
? argv[labelIdx + 1]
: typeof env.MESH_CLIENT_SCHEMA_WORKFLOW_LABEL === 'string' &&
env.MESH_CLIENT_SCHEMA_WORKFLOW_LABEL
? env.MESH_CLIENT_SCHEMA_WORKFLOW_LABEL
: undefined;

const currFile = path.join(ROOT, SCHEMA_REL);
const currSchema = readSchemaVersionFromFile(currFile);

Expand All @@ -232,6 +243,7 @@ export async function runSchemaReleaseCompare(argv, env = process.env) {
prevSchema,
prevTag,
schemaBumped,
workflowLabel,
});

writeStepSummary(markdown, env.GITHUB_STEP_SUMMARY);
Expand Down
14 changes: 14 additions & 0 deletions scripts/ci-schema-release-compare.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,26 @@ describe('formatSchemaCompareMarkdown', () => {
schemaBumped: true,
});
expect(md).toContain('Test build — not an official release');
expect(md).toContain('Build Binaries');
expect(md).toContain('49');
expect(md).toContain('v5.26.0');
expect(md).toContain('48 → 49');
expect(md).toContain('cannot downgrade');
});

it('uses a custom workflow label for Flatpak test builds', () => {
const md = formatSchemaCompareMarkdown({
mode: 'test-build',
currSchema: 49,
prevSchema: 48,
prevTag: 'v5.26.0',
schemaBumped: true,
workflowLabel: 'Build Flatpak',
});
expect(md).toContain('Build Flatpak');
expect(md).not.toContain('Build Binaries');
});

it('notes when there is no bump', () => {
const md = formatSchemaCompareMarkdown({
mode: 'test-build',
Expand Down