Files
openswarm/electron/releaseShell.test.js

77 lines
4.4 KiB
JavaScript

// Every installed copy polls github.com/openswarm-ai/openswarm for updates, and the landing page links
// its downloads there. When the source moves to a private repo that public repo becomes a releases-only
// shell, so every path that publishes or downloads a build must name the shell, never "the repo I run in".
const test = require('node:test');
const assert = require('node:assert');
const fs = require('fs');
const path = require('path');
const pkg = require('./package.json');
const SHELL = 'openswarm-ai/openswarm';
const root = path.join(__dirname, '..');
const read = (rel) => fs.readFileSync(path.join(root, rel), 'utf8');
test('electron-builder publishes into the shell', () => {
assert.deepStrictEqual(pkg.build.publish, { provider: 'github', owner: 'openswarm-ai', repo: 'openswarm' });
});
test('both updater feeds in main.js point at the shell', () => {
const main = read('electron/main.js');
assert.ok(main.includes(`https://github.com/${SHELL}/releases/latest/download/RELEASES`), 'the Squirrel probe');
assert.ok(main.includes(`setFeedURL({ url: 'https://github.com/${SHELL}/releases/latest/download/' })`), 'the Squirrel feed');
});
test('the Windows installer icon and alias upload name the shell', () => {
const ps1 = read('scripts/build-app-win.ps1');
assert.ok(ps1.includes(`https://raw.githubusercontent.com/${SHELL}/main/electron/build/icon.ico`), 'Squirrel reads the icon off the shell main branch');
assert.ok(ps1.includes(`gh release upload "v$version" $AliasExe --repo ${SHELL} --clobber`));
assert.ok(fs.existsSync(path.join(root, 'release-shell/electron/build/icon.ico')), 'the shell must keep the icon at that path');
});
test('every release workflow publishes with the shell token and names the shell', () => {
for (const wf of ['release-macos.yml', 'release-windows.yml']) {
const y = read(`.github/workflows/${wf}`);
const check = y.indexOf('run: bash scripts/release/check-shell-token.sh');
const build = y.indexOf('- name: Build app');
assert.ok(check > 0 && check < build, `${wf}: the shell check runs before the build`);
const buildEnv = y.slice(build, y.indexOf('run:', build));
assert.ok(buildEnv.includes('GH_TOKEN: ${{ secrets.RELEASE_SHELL_TOKEN }}'), `${wf}: the build publishes with the shell token`);
assert.ok(!y.includes('GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}'), `${wf}: a workflow token only writes to its own repo`);
}
const win = read('.github/workflows/release-windows.yml');
assert.ok(win.includes(`GH_REPO: ${SHELL}`), 'gh release calls on Windows land in the shell');
});
test('no download or gate path reads the repo it runs in', () => {
for (const wf of ['promotion-gate.yml', 'intel-x64-verify.yml', 'smoke-windows-packaged.yml']) {
const y = read(`.github/workflows/${wf}`);
assert.ok(!y.includes('github.repository') && !y.includes('GITHUB_REPOSITORY'), `${wf} must name ${SHELL}`);
assert.ok(y.includes(SHELL), `${wf} names the shell`);
}
});
test('the source repo gate is by hand and the shell copy answers release events', () => {
assert.ok(!read('.github/workflows/promotion-gate.yml').includes('\n release:'), 'release events never fire in the build repo');
const shellGate = read('release-shell/.github/workflows/promotion-gate.yml');
assert.ok(shellGate.includes('\n release:\n types: [published, released, prereleased]'));
assert.ok(shellGate.includes('node scripts/release/verify-release.js'));
});
test('the shell carries byte-identical copies of what its gate and installer need', () => {
for (const rel of ['scripts/release/verify-release.js', 'electron/build/icon.ico']) {
assert.ok(fs.readFileSync(path.join(root, rel)).equals(fs.readFileSync(path.join(root, 'release-shell', rel))), `${rel} drifted`);
}
});
test('publish.sh sends releases and the ENG-319 tag guard to the shell, not to origin', () => {
const sh = read('publish.sh');
assert.ok(sh.includes(`export GH_REPO="\${GH_REPO:-${SHELL}}"`));
assert.ok(sh.includes('gh api -X DELETE "repos/$GH_REPO/git/refs/tags/v$VERSION"'));
assert.ok(!sh.includes('git push origin ":refs/tags/'), 'the build repo tag is not the feed tag');
});
test('a push runs only the Windows suite leg; Mac minutes are spent on purpose', () => {
const y = read('.github/workflows/suites-matrix.yml');
assert.ok(y.includes(`os: \${{ github.event_name == 'push' && fromJSON('["windows-latest"]') || fromJSON('["macos-latest", "macos-15-intel", "windows-latest"]') }}`));
});