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
21 changes: 12 additions & 9 deletions .github/DESKTOP_NIGHTLY.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,22 @@

Desktop Nightly is an ephemeral developer snapshot, not an Apache release. It builds the current `main` commit every day so contributors can try recent Desktop changes and report problems without waiting for an ASF source-release vote.

The npm publication workflow gives each snapshot an immutable version such as `0.2.0-dev.42.20260829`. The run number is the sole ordering authority. After that exact npm version is public, it triggers Desktop Nightly with a version-only artifact; the authenticated workflow event supplies the exact source commit and upstream run. A packaged Nightly accepts updates only from `https://nightlies.apache.org/maka/desktop/`, advances only to a higher run number, and verifies that downloaded bytes were attested by `.github/workflows/desktop-nightly.yml` on `main`. A formal Desktop build continues to use the GitHub Release feed and the formal product-release attestation identity.
The npm publication workflow gives each snapshot an immutable version such as `0.2.0-dev.42.20260829`. The run number is the sole ordering authority. After that exact npm version is public, it triggers Desktop Nightly with a version-only artifact; the authenticated workflow event supplies the exact source commit and upstream run. Each fresh Desktop Nightly creates a protected `v<version>` tag and one GitHub draft prerelease containing the macOS and Windows packages, blockmaps, `dev-mac.yml`, `dev.yml`, and one offline Sigstore bundle. The workflow verifies every remote asset before it publishes the prerelease as non-Latest. Packaged Nightlies use the GitHub `dev` channel and verify that downloaded bytes were attested by `.github/workflows/desktop-nightly.yml` on `main`. A formal Desktop build uses the separate stable GitHub Release channel and formal product-release attestation identity.

Nightly currently uses the same application identity as the formal Desktop. Installing it replaces the existing Maka installation rather than creating a second side-by-side app. Its user data remains in the same location. Testers who need the formal build should reinstall that build before returning to the formal channel.
Nightly currently uses the same application identity as the formal Desktop. Installing it replaces the existing Maka installation rather than creating a second side-by-side app. Its user data remains in the same location. Testers who need the formal build should reinstall that build before returning to the formal channel. Builds previously downloaded from `nightlies.apache.org` do not migrate automatically; testers must install the newest GitHub prerelease once, after which GitHub Nightlies update automatically.

## One-time setup

1. Ask Apache Infra to allow `apache/maka` to publish GitHub Actions output to `nightlies.apache.org` and whitelist the repository for the standard `NIGHTLIES_RSYNC_HOST`, `NIGHTLIES_RSYNC_KEY`, `NIGHTLIES_RSYNC_PATH`, `NIGHTLIES_RSYNC_PORT`, and `NIGHTLIES_RSYNC_USER` secrets.
2. After the checked-in `.asf.yaml` reaches `main`, verify that ASF reconciliation created the `nightly` GitHub Environment with only `main` permitted and no approval gate. Do not maintain that policy manually in GitHub. Verify that its jobs can read the five Infra-provided Nightlies secrets. Configure its macOS signing and notarization secrets: `CSC_LINK`, `CSC_KEY_PASSWORD`, `APPLE_API_KEY`, `APPLE_API_KEY_ID`, and `APPLE_API_ISSUER`. Do not expose these secrets to repository-wide or pull-request workflows.
3. Configure npm Trusted Publishing for `apache/maka` and `.github/workflows/npm-publication.yml`, restricted to the `npm-publication` Environment and with both `npm publish` and `npm stage publish` allowed. Do not create or store a long-lived npm token.
4. After npm Trusted Publishing is ready, set `NPM_NIGHTLY_ENABLED` to `true`, run `npm publication` from `main` with `channel=nightly`, and verify the exact npm version and `nightly` dist-tag. This does not depend on Desktop Infra.
5. After Infra publishing and the `nightly` Environment secrets are ready, set `DESKTOP_NIGHTLY_ENABLED` to `true` and start a fresh npm Nightly. Confirm that its successful run triggers `Desktop Nightly`.
6. Verify the download page, `latest-mac.yml`, and `latest.yml` under `https://nightlies.apache.org/maka/desktop/`, install both platform artifacts on clean machines, and confirm one automatic update before sharing the channel with testers.
1. After the checked-in `.asf.yaml` reaches `main`, verify that ASF reconciliation created the `nightly` GitHub Environment with only `main` permitted and no approval gate. Do not maintain that policy manually in GitHub. Configure its macOS signing and notarization secrets: `CSC_LINK`, `CSC_KEY_PASSWORD`, `APPLE_API_KEY`, `APPLE_API_KEY_ID`, and `APPLE_API_ISSUER`. Do not expose these secrets to repository-wide or pull-request workflows.
2. Configure npm Trusted Publishing for `apache/maka` and `.github/workflows/npm-publication.yml`, restricted to the `npm-publication` Environment and with both `npm publish` and `npm stage publish` allowed. Do not create or store a long-lived npm token.
3. Enable GitHub Immutable Releases for `apache/maka` before distributing Desktop Nightlies so published tags and assets cannot be replaced or deleted.
4. After npm Trusted Publishing is ready, set `NPM_NIGHTLY_ENABLED` to `true`, run `npm publication` from `main` with `channel=nightly`, and verify the exact npm version and `nightly` dist-tag.
5. Set `DESKTOP_NIGHTLY_ENABLED` to `true` and manually dispatch a fresh npm Nightly. Confirm that its successful run triggers `Desktop Nightly`. Do not rerun a failed attempt in place.
6. Verify that `v<version>` points to the exact source SHA and that its GitHub Release is published with Draft off, Prerelease on, Latest off, Immutable on, and exactly the nine expected assets. Install that prerelease on both platforms.
7. Publish one later fresh Nightly and confirm a GitHub-to-GitHub automatic and differential update on both platforms before sharing the channel with testers.

The npm schedule starts at 18:17 UTC. Before changing the npm tag, the workflow requires its run number to exceed the current `nightly` version. Desktop applies the same check against both remote feed files before uploading anything. It then appends a new immutable Desktop version directory and advances the mutable update metadata last. Each platform feed file is replaced independently after its complete payload exists, so an interrupted feed transfer may temporarily leave macOS and Windows on different valid Nightly versions. Do not rerun a failed workflow attempt in place; start a fresh npm Nightly so it receives a new version. The Maka project owns historical payload cleanup separately from publication. Cleanup must never rewrite a published version or delete one referenced by a feed. Apache Nightlies storage is temporary; it must not be used as a formal release archive.
The npm schedule starts at 18:17 UTC. Before changing the npm tag, the workflow requires its run number to exceed the current `nightly` version. Desktop assembles and verifies a draft before one publish mutation; a packaging, attestation, tag, upload, or digest failure leaves no partially published GitHub Release. Never rerun a failed workflow attempt in place; dispatch a fresh npm Nightly with a newer version.

GitHub Release retention is intentionally outside this workflow. Do not delete an old Nightly prerelease or its tag while any installed client may need its payload or blockmap. Disabling `DESKTOP_NIGHTLY_ENABLED` stops new Desktop publication without mutating tags or releases.

Remote Runtime Host setup uses the exact `maka-agent@<nightly-version>` package embedded in the Desktop manifest. The npm package is verified before Desktop artifacts become visible, so clean remote setup never depends on an unpublished Runtime Host version.
106 changes: 42 additions & 64 deletions .github/workflows/desktop-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -184,14 +184,14 @@ jobs:
"apps/desktop/release/Maka-$NIGHTLY_VERSION-mac-arm64.dmg" \
"apps/desktop/release/Maka-$NIGHTLY_VERSION-mac-arm64.zip" \
"apps/desktop/release/Maka-$NIGHTLY_VERSION-mac-arm64.zip.blockmap" \
apps/desktop/release/latest-mac.yml \
apps/desktop/release/dev-mac.yml \
"$STAGE_DIRECTORY/"
else
cp -- \
"apps/desktop/release/Maka-$NIGHTLY_VERSION-win-x64.exe" \
"apps/desktop/release/Maka-$NIGHTLY_VERSION-win-x64.exe.blockmap" \
"apps/desktop/release/Maka-$NIGHTLY_VERSION-win-x64.zip" \
apps/desktop/release/latest.yml \
apps/desktop/release/dev.yml \
"$STAGE_DIRECTORY/"
fi

Expand All @@ -212,7 +212,7 @@ jobs:
permissions:
artifact-metadata: write
attestations: write
contents: read
contents: write
id-token: write
steps:
- name: Reject in-place workflow reruns
Expand Down Expand Up @@ -243,29 +243,26 @@ jobs:
path: ${{ github.workspace }}/.nightly-input
merge-multiple: true

- name: Stage the versioned Nightly site
- name: Stage the exact GitHub Release assets
env:
NIGHTLY_VERSION: ${{ needs.identity.outputs.version }}
SOURCE_COMMIT: ${{ needs.identity.outputs.source_commit }}
run: |
node scripts/desktop-nightly.mjs stage \
"$GITHUB_WORKSPACE/.nightly-input" \
"$GITHUB_WORKSPACE/.nightly-publish" \
"$NIGHTLY_VERSION" \
"$SOURCE_COMMIT"
"$GITHUB_WORKSPACE/.nightly-stage" \
"$NIGHTLY_VERSION"

- name: Attest the exact Nightly payloads
- name: Attest every GitHub Nightly asset subject
id: attest
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
with:
subject-path: ${{ github.workspace }}/.nightly-publish/versions/${{ needs.identity.outputs.version }}/*
subject-path: ${{ github.workspace }}/.nightly-stage/release/*

- name: Verify the issued Nightly provenance
env:
ATTESTATION_BUNDLE: ${{ steps.attest.outputs.bundle-path }}
CERTIFICATE_IDENTITY: https://github.com/${{ github.repository }}/.github/workflows/desktop-nightly.yml@refs/heads/main
GH_TOKEN: ${{ github.token }}
NIGHTLY_VERSION: ${{ needs.identity.outputs.version }}
run: |
verified=0
while IFS= read -r -d '' artifact; do
Expand All @@ -275,70 +272,51 @@ jobs:
--cert-identity "$CERTIFICATE_IDENTITY" \
--cert-oidc-issuer https://token.actions.githubusercontent.com
verified=$((verified + 1))
done < <(find "$GITHUB_WORKSPACE/.nightly-publish/versions/$NIGHTLY_VERSION" -maxdepth 1 -type f -print0)
if (( verified == 0 )); then
echo "No Desktop Nightly artifacts were verified" >&2
done < <(find "$GITHUB_WORKSPACE/.nightly-stage/release" -maxdepth 1 -type f -print0)
if (( verified != 8 )); then
echo "Expected 8 verified Desktop Nightly subjects, found $verified" >&2
exit 1
fi

- name: Add the offline provenance bundle
- name: Add the one offline provenance bundle
env:
ATTESTATION_BUNDLE: ${{ steps.attest.outputs.bundle-path }}
NIGHTLY_VERSION: ${{ needs.identity.outputs.version }}
run: >-
cp -- "$ATTESTATION_BUNDLE"
"$GITHUB_WORKSPACE/.nightly-publish/versions/$NIGHTLY_VERSION/Maka-$NIGHTLY_VERSION-attestation.sigstore.json"
run: |
node scripts/desktop-nightly.mjs add-attestation \
"$GITHUB_WORKSPACE/.nightly-stage" \
"$NIGHTLY_VERSION" \
"$ATTESTATION_BUNDLE"

- name: Prepare authenticated Nightlies SSH transport
- name: Ensure the exact versioned Nightly tag
env:
NIGHTLIES_RSYNC_HOST: ${{ secrets.NIGHTLIES_RSYNC_HOST }}
NIGHTLIES_RSYNC_KEY: ${{ secrets.NIGHTLIES_RSYNC_KEY }}
NIGHTLIES_RSYNC_PATH: ${{ secrets.NIGHTLIES_RSYNC_PATH }}
NIGHTLIES_RSYNC_PORT: ${{ secrets.NIGHTLIES_RSYNC_PORT }}
NIGHTLIES_RSYNC_USER: ${{ secrets.NIGHTLIES_RSYNC_USER }}
run: |
test -n "$NIGHTLIES_RSYNC_HOST"
test -n "$NIGHTLIES_RSYNC_KEY"
test -n "$NIGHTLIES_RSYNC_PATH"
test -n "$NIGHTLIES_RSYNC_USER"
[[ "$NIGHTLIES_RSYNC_PORT" =~ ^[0-9]{1,5}$ ]]
(( NIGHTLIES_RSYNC_PORT >= 1 && NIGHTLIES_RSYNC_PORT <= 65535 ))
ssh_directory="$RUNNER_TEMP/nightlies-ssh"
install -m 700 -d "$ssh_directory"
umask 077
printf '%s\n' "$NIGHTLIES_RSYNC_KEY" > "$ssh_directory/key"
{
echo "NIGHTLIES_RSYNC_BASE=$NIGHTLIES_RSYNC_USER@$NIGHTLIES_RSYNC_HOST:${NIGHTLIES_RSYNC_PATH%/}"
echo "NIGHTLIES_RSYNC_TARGET=$NIGHTLIES_RSYNC_USER@$NIGHTLIES_RSYNC_HOST:${NIGHTLIES_RSYNC_PATH%/}/maka/desktop"
echo "RSYNC_RSH=ssh -i $ssh_directory/key -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p $NIGHTLIES_RSYNC_PORT"
} >> "$GITHUB_ENV"

- name: Ensure the Nightly destination exists
GH_TOKEN: ${{ github.token }}
NIGHTLY_VERSION: ${{ needs.identity.outputs.version }}
SOURCE_COMMIT: ${{ needs.identity.outputs.source_commit }}
run: |
mkdir -p .nightly-empty/maka/desktop
rsync -rlptDz --protect-args .nightly-empty/maka/ "$NIGHTLIES_RSYNC_BASE/maka/"
gh auth setup-git
node scripts/product-release-tag.mjs ensure "v$NIGHTLY_VERSION" "$SOURCE_COMMIT"

- name: Require the Desktop Nightly feed to advance
- name: Prepare and verify the draft GitHub Prerelease
env:
GH_TOKEN: ${{ github.token }}
NIGHTLY_VERSION: ${{ needs.identity.outputs.version }}
SOURCE_COMMIT: ${{ needs.identity.outputs.source_commit }}
run: |
mkdir -p .nightly-current-feed
rsync -rlptDz --protect-args \
--include='/latest-mac.yml' \
--include='/latest.yml' \
--exclude='*' \
"$NIGHTLIES_RSYNC_TARGET/" \
.nightly-current-feed/
node scripts/desktop-nightly.mjs assert-feed-advance \
.nightly-current-feed \
"$NIGHTLY_VERSION"

- name: Publish immutable Nightly payloads
run: rsync -rlptDvz --protect-args .nightly-publish/versions/ "$NIGHTLIES_RSYNC_TARGET/versions/"

- name: Advance the Nightly update feed last
run: rsync -rlptDvz --protect-args .nightly-publish/feed/ "$NIGHTLIES_RSYNC_TARGET/"
node scripts/desktop-nightly-release.mjs prepare \
"$GITHUB_WORKSPACE/.nightly-stage/release" \
"$NIGHTLY_VERSION" \
"$SOURCE_COMMIT" \
"$GITHUB_REPOSITORY"

- name: Remove the temporary Nightlies credentials
if: always()
run: rm -f "$RUNNER_TEMP/nightlies-ssh/key"
- name: Publish the complete GitHub Prerelease
env:
GH_TOKEN: ${{ github.token }}
NIGHTLY_VERSION: ${{ needs.identity.outputs.version }}
SOURCE_COMMIT: ${{ needs.identity.outputs.source_commit }}
run: |
node scripts/desktop-nightly-release.mjs publish \
"$GITHUB_WORKSPACE/.nightly-stage/release" \
"$NIGHTLY_VERSION" \
"$SOURCE_COMMIT" \
"$GITHUB_REPOSITORY"
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
</p>

<p align="center">
<a href="https://nightlies.apache.org/maka/desktop/"><img src="https://img.shields.io/badge/Download%20Desktop%20Nightly-1F6FEB?style=for-the-badge" alt="Download Desktop Nightly" /></a><br/>
<a href="https://github.com/apache/maka/releases"><img src="https://img.shields.io/badge/Download%20Desktop%20Nightly-1F6FEB?style=for-the-badge" alt="Download Desktop Nightly" /></a><br/>
Daily builds from <code>main</code> for developers and testers. Not an ASF release, not intended for production use.
</p>

Expand Down Expand Up @@ -101,7 +101,7 @@ Apache Maka has not made an Apache release yet. Everything currently published f

Once Apache releases exist, the official release is the source release published by the ASF and approved by the podling PPMC and the Incubator PMC. A package built from that source and distributed elsewhere, for example through a package registry or as a Desktop installer, is a convenience artifact rather than the release itself, and it is valid only when it is built from an approved source release. [`.github/ASF_SOURCE_RELEASE.md`](./.github/ASF_SOURCE_RELEASE.md) holds the candidate contract, signing path, and verification steps.

[Desktop Nightly](https://nightlies.apache.org/maka/desktop/) is built daily from `main` for developers and testers. It is not an ASF release and is not intended for production use. Desktop currently targets Apple Silicon Macs (`arm64`). Intel Macs and Linux are not supported yet. [Windows](docs/windows-support.md) is an unsigned preview, not a supported release tier.
[Desktop Nightly](https://github.com/apache/maka/releases) is built daily from `main` for developers and testers. Choose the newest **Maka Desktop Nightly** prerelease; after installation, the app updates automatically on the Nightly channel. It is not an ASF release and is not intended for production use. Desktop currently targets Apple Silicon Macs (`arm64`). Intel Macs and Linux are not supported yet. [Windows](docs/windows-support.md) is an unsigned preview, not a supported release tier.

### Requirements

Expand Down
4 changes: 2 additions & 2 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
</p>

<p align="center">
<a href="https://nightlies.apache.org/maka/desktop/"><img src="https://img.shields.io/badge/%E4%B8%8B%E8%BD%BD%20Desktop%20Nightly-1F6FEB?style=for-the-badge" alt="下载 Desktop Nightly" /></a><br/>
<a href="https://github.com/apache/maka/releases"><img src="https://img.shields.io/badge/%E4%B8%8B%E8%BD%BD%20Desktop%20Nightly-1F6FEB?style=for-the-badge" alt="下载 Desktop Nightly" /></a><br/>
每天从 <code>main</code> 构建,面向开发者和测试者。不是 ASF release,也不适合生产使用。
</p>

Expand Down Expand Up @@ -99,7 +99,7 @@ Apache Maka 目前还没有发布过 Apache release。当前从本仓库或包

在 Apache release 出现之后,官方 release 指的是由 ASF 发布、并经 podling PPMC 和 Incubator PMC 批准的源码 release。由该源码构建并通过其他渠道分发的包,例如包管理器中的包或 Desktop 安装程序,属于 convenience artifact,本身不是 release,并且只有在由获批源码 release 构建时才有效。候选契约、签名路径和验包步骤见 [`.github/ASF_SOURCE_RELEASE.md`](./.github/ASF_SOURCE_RELEASE.md)。

[Desktop Nightly](https://nightlies.apache.org/maka/desktop/) 面向开发者和测试者,每天从 `main` 构建。它不是 ASF release,不适合生产使用。Desktop 目前面向 Apple Silicon Mac(`arm64`)。暂不支持 Intel Mac 和 Linux。[Windows](docs/windows-support.md) 是未签名预览,不是正式支持的发布层级。
[Desktop Nightly](https://github.com/apache/maka/releases) 面向开发者和测试者,每天从 `main` 构建。请选择最新的 **Maka Desktop Nightly** prerelease;安装后,应用会在 Nightly 渠道自动更新。它不是 ASF release,不适合生产使用。Desktop 目前面向 Apple Silicon Mac(`arm64`)。暂不支持 Intel Mac 和 Linux。[Windows](docs/windows-support.md) 是未签名预览,不是正式支持的发布层级。

### 环境要求

Expand Down
3 changes: 1 addition & 2 deletions apps/desktop/electron-builder.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';
import {
DESKTOP_NIGHTLY_FEED_URL,
resolveDesktopBuildVersion,
resolveRuntimeHostSetupPackage,
} from '../../scripts/desktop-nightly.mjs';
Expand Down Expand Up @@ -287,7 +286,7 @@ export function resolveDesktopBuilderConfig(environment = process.env) {
runtimeHostSetupPackage: resolveRuntimeHostSetupPackage(rootManifest.version, environment),
makaUpdateChannel: 'nightly',
},
publish: [{ provider: 'generic', url: DESKTOP_NIGHTLY_FEED_URL, channel: 'latest' }],
publish: [{ provider: 'github', owner: 'apache', repo: 'maka', channel: 'dev' }],
};
}

Expand Down
Loading