fix(release): surface companion build and secure GitWorkshop deps

This commit is contained in:
archipelago
2026-09-11 06:10:59 -04:00
parent ef8c3a76be
commit dac29baf97
10 changed files with 1601 additions and 37 deletions
@@ -0,0 +1,42 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import {
companionRelease,
companionReleaseMarker,
loadCompanionRelease,
} from '../useCompanionRelease'
beforeEach(() => {
companionRelease.value = null
})
afterEach(() => {
vi.unstubAllGlobals()
})
describe('companion release metadata', () => {
it('uses the Android build number as the durable prompt marker', () => {
expect(companionReleaseMarker({ versionName: '0.5.32', versionCode: 52 })).toBe('build:52')
expect(companionReleaseMarker({ versionName: '0.5.32', versionCode: 0 })).toBe(
'version:0.5.32',
)
expect(companionReleaseMarker(null)).toBe('1')
})
it('loads the same no-cache metadata used by the download prompt', async () => {
const fetchMock = vi.fn().mockResolvedValue({
ok: true,
json: async () => ({ versionName: '0.5.32', versionCode: 52 }),
})
vi.stubGlobal('fetch', fetchMock)
await expect(loadCompanionRelease()).resolves.toEqual({
versionName: '0.5.32',
versionCode: 52,
})
expect(companionRelease.value).toEqual({ versionName: '0.5.32', versionCode: 52 })
expect(fetchMock).toHaveBeenCalledWith('/packages/archipelago-companion.json', {
cache: 'no-store',
})
})
})
@@ -0,0 +1,51 @@
import { ref } from "vue";
export interface CompanionRelease {
versionName: string;
versionCode: number;
}
// One shared value keeps the Discover banner and the automatic/manual
// Companion prompt on exactly the same release metadata.
export const companionRelease = ref<CompanionRelease | null>(null);
let releaseRequest: Promise<CompanionRelease | null> | null = null;
export function loadCompanionRelease(): Promise<CompanionRelease | null> {
if (companionRelease.value) return Promise.resolve(companionRelease.value);
if (releaseRequest) return releaseRequest;
releaseRequest = fetch("/packages/archipelago-companion.json", {
cache: "no-store",
})
.then(async (response) => {
if (!response.ok) return null;
const metadata = await response.json();
if (
!metadata ||
typeof metadata.versionName !== "string" ||
!metadata.versionName
)
return null;
companionRelease.value = {
versionName: metadata.versionName,
versionCode: Number(metadata.versionCode) || 0,
};
return companionRelease.value;
})
.catch(() => null)
.finally(() => {
releaseRequest = null;
});
return releaseRequest;
}
export function companionReleaseMarker(
release: CompanionRelease | null,
): string {
if (release?.versionCode) return `build:${release.versionCode}`;
if (release?.versionName) return `version:${release.versionName}`;
return "1";
}