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
7 changes: 7 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,12 @@ jobs:
bun ./packages/redrob/script/launcher-assets.ts \
--version "$VERSION" --unsigned unsigned --signed signed --out assets

# The icon redrob-launcher.json names: the 512 px mark as one more release asset, so Redrob
# Launcher's catalog shows this release's own logo. The shared publish job is told the name
# (`launcher_icon`) and writes the manifest with it over every asset.
- name: Add the Redrob Launcher icon
run: cp packages/identity/mark-512x512.png assets/redrob-code.png

# The marker install.sh and `redrob upgrade` read to answer "what is the newest
# version". `releases/latest/download/VERSION` resolves to whichever release is newest,
# so no client has to hardcode a tag and nothing here consults the GitHub API, which is
Expand Down Expand Up @@ -614,6 +620,7 @@ jobs:
version: ${{ needs.version.outputs.version }}
title: Redrob Code
launcher_manifest: true
launcher_icon: redrob-code.png
publish: true
tag: ${{ needs.version.outputs.tag }}
target: ${{ needs.version.outputs.sha }}
9 changes: 6 additions & 3 deletions packages/redrob/script/launcher-assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,17 @@ export const STEM = "redrob-code"
/**
* The release manifest the launcher reads beside the installers (the launcher's
* `docs/release-manifest.md`). `schema` is 1; `sharedAccount` is true because every release from
* here on reads the launcher's shared account file as its last console-key fallback.
* here on reads the launcher's shared account file as its last console-key fallback; `icon` names
* the square PNG asset of the same release the launcher shows in its catalog -- the 512 px mark
* from `packages/identity`, which the release workflow stages beside the installers under this name.
*/
export const MANIFEST_NAME = "redrob-launcher.json"
export const MANIFEST = { schema: 1, sharedAccount: true } as const
export const ICON_NAME = "redrob-code.png"
export const MANIFEST = { schema: 1, sharedAccount: true, icon: ICON_NAME } as const

/** The manifest's bytes, exactly as the launcher contract spells them, newline-terminated. */
export function manifestText(): string {
return `{ "schema": ${MANIFEST.schema}, "sharedAccount": ${MANIFEST.sharedAccount} }\n`
return `{ "schema": ${MANIFEST.schema}, "sharedAccount": ${MANIFEST.sharedAccount}, "icon": "${MANIFEST.icon}" }\n`
}

/** Writes the manifest into `out` and returns its path. */
Expand Down
12 changes: 6 additions & 6 deletions packages/redrob/test/installation/launcher-assets.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,19 +107,19 @@ describe("launcher asset names", () => {

/**
* `redrob-launcher.json` is how the launcher learns, without a launcher release, that this release
* reads its shared account file (the launcher's `docs/release-manifest.md`). Exactly `{ "schema": 1,
* "sharedAccount": true }`: a wrong schema is ignored by the launcher and a false flag hides the
* sign-in, both silently, so the bytes are pinned here.
* reads its shared account file and which asset is its icon (the launcher's `docs/release-manifest.md`).
* Exactly `{ "schema": 1, "sharedAccount": true, "icon": "redrob-code.png" }`: a wrong schema is
* ignored by the launcher and a false flag hides the sign-in, both silently, so the bytes are pinned here.
*/
describe("release manifest", () => {
test("is the launcher contract, verbatim", () => {
expect(MANIFEST_NAME).toBe("redrob-launcher.json")
expect(manifestText()).toBe('{ "schema": 1, "sharedAccount": true }\n')
expect(manifestText()).toBe('{ "schema": 1, "sharedAccount": true, "icon": "redrob-code.png" }\n')
const parsed = JSON.parse(manifestText())
expect(parsed).toEqual({ schema: 1, sharedAccount: true })
expect(parsed).toEqual({ schema: 1, sharedAccount: true, icon: "redrob-code.png" })
expect(parsed.schema).toBe(1)
expect(parsed.sharedAccount).toBe(true)
expect(MANIFEST).toEqual({ schema: 1, sharedAccount: true })
expect(MANIFEST).toEqual({ schema: 1, sharedAccount: true, icon: "redrob-code.png" })
})

test("a release directory without it fails the check", () => {
Expand Down
Loading