Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ensure Fiddle on macOS updates through v0.35.1 #150

Merged
merged 2 commits into from
Dec 7, 2023
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
58 changes: 48 additions & 10 deletions src/updates.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,30 @@ class Updates {
} else if (version && !semver.valid(version)) {
badRequest(res, `Invalid SemVer: "${version}"`);
} else if (file === "RELEASES") {
await this.handleReleases(res, account, repository, platform);
await this.handleReleases(res, account, repository, platform, version);
} else {
await this.handleUpdate(res, account, repository, platform, version);
}
}

async handleReleases(res, account, repository, platform) {
const latest = await this.cachedGetLatest(account, repository, platform);
async handleReleases(res, account, repository, platform, version) {
const latest = await this.cachedGetLatest(
account,
repository,
platform,
version
);
if (!latest || !latest.RELEASES) return notFound(res);
res.end(latest.RELEASES);
}

async handleUpdate(res, account, repository, platform, version) {
const latest = await this.cachedGetLatest(account, repository, platform);
const latest = await this.cachedGetLatest(
account,
repository,
platform,
version
);

if (!latest) {
const message = platform.includes(PLATFORM.DARWIN)
Expand Down Expand Up @@ -119,8 +129,12 @@ class Updates {
}
}

async cachedGetLatest(account, repository, platform) {
const key = `${account}/${repository}`;
async cachedGetLatest(account, repository, platform, version) {
const tag = needsSpecificReleaseTag(account, repository, platform, version);

const key = tag
? `${account}/${repository}-${tag}`
: `${account}/${repository}`;
let latest = await this.cache.get(key);

if (latest) {
Expand All @@ -144,7 +158,7 @@ class Updates {
}
}

latest = await this.getLatest(account, repository);
latest = await this.getLatest(account, repository, platform, version);

if (latest) {
await this.cache.set(key, latest);
Expand All @@ -161,10 +175,15 @@ class Updates {
return latest && latest[platform];
}

async getLatest(account, repository) {
async getLatest(account, repository, platform, version) {
account = encodeURIComponent(account);
repository = encodeURIComponent(repository);
const url = `https://api.github.com/repos/${account}/${repository}/releases?per_page=100`;

const tag = needsSpecificReleaseTag(account, repository, platform, version);

const url = tag
? `https://api.github.com/repos/${account}/${repository}/releases/tags/${tag}`
: `https://api.github.com/repos/${account}/${repository}/releases?per_page=100`;
const headers = { Accept: "application/vnd.github.preview" };
if (this.token) headers.Authorization = `token ${this.token}`;
const res = await fetch(url, { headers });
Expand All @@ -184,7 +203,10 @@ class Updates {

const latest = {};

const releases = await res.json();
let releases = await res.json();
if (!Array.isArray(releases)) {
releases = [releases];
}
for (const release of releases) {
if (
!semver.valid(release.tag_name) ||
Expand Down Expand Up @@ -241,6 +263,22 @@ class Updates {
}
}

// Any logic to require a specific release when updating should go here
const needsSpecificReleaseTag = (account, repository, platform, version) => {
const FIDDLE_TRANSITION_VERSION = "v0.35.1";

if (
account === "electron" &&
semver.lt(version, FIDDLE_TRANSITION_VERSION) &&
[PLATFORM_ARCH.DARWIN_X64, PLATFORM_ARCH.DARWIN_ARM64].includes(platform) &&
repository === "fiddle"
) {
return FIDDLE_TRANSITION_VERSION;
}

return null;
};

const hasAllAssets = (latest) => {
return !!(
latest[PLATFORM_ARCH.DARWIN_X64] &&
Expand Down
156 changes: 156 additions & 0 deletions test/update.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,74 @@ nock("https://api.github.com")
},
],
},
])
.get("/repos/electron/fiddle/releases?per_page=100")
.reply(200, [
{
name: "v0.36.0",
tag_name: "v0.36.0",
body: "notes",
assets: [
{
name: "mac.zip",
browser_download_url: "mac.zip",
},
{
name: "mac-arm64.zip",
browser_download_url: "mac-arm64.zip",
},
{
name: "electron-fiddle-0.36.0-win32-x64-setup.exe",
browser_download_url: "electron-fiddle-0.36.0-win32-x64-setup.exe",
},
{
name: "electron-fiddle-0.36.0-win32-ia32-setup.exe",
browser_download_url: "electron-fiddle-0.36.0-win32-ia32-setup.exe",
},
{
name: "electron-fiddle-0.36.0-win32-arm64-setup.exe",
browser_download_url: "electron-fiddle-0.36.0-win32-arm64-setup.exe",
},
],
},
])
.get("/repos/electron/fiddle/releases/tags/v0.35.1")
.reply(200, [
{
name: "v0.35.1",
tag_name: "v0.35.1",
body: "notes",
assets: [
{
name: "mac.zip",
browser_download_url: "mac.zip",
},
{
name: "mac-arm64.zip",
browser_download_url: "mac-arm64.zip",
},
{
name: "electron-fiddle-1.0.0-win32-x64-setup.exe",
browser_download_url: "electron-fiddle-1.0.0-win32-x64-setup.exe",
},
{
name: "electron-fiddle-1.0.0-win32-ia32-setup.exe",
browser_download_url: "electron-fiddle-1.0.0-win32-ia32-setup.exe",
},
{
name: "electron-fiddle-1.0.0-win32-arm64-setup.exe",
browser_download_url: "electron-fiddle-1.0.0-win32-arm64-setup.exe",
},
],
},
]);
nock("https://github.com")
.get("/electron/fiddle/releases/download/v0.35.1/RELEASES")
.times(3)
.reply(200, "HASH name.nupkg NUMBER")
.get("/electron/fiddle/releases/download/v0.36.0/RELEASES")
.times(3)
.reply(200, "HASH name.nupkg NUMBER")
.get("/owner/repo/releases/download/1.0.0/RELEASES")
.times(3)
.reply(200, "HASH name.nupkg NUMBER")
Expand Down Expand Up @@ -447,3 +513,93 @@ test("Updates", async (t) => {
server.close();
});
});

test("electron/fiddle", async (t) => {
const { server, address } = await createServer();

await t.test("first updates to v0.35.1", async (t) => {
await t.test("on macOS", async (t) => {
for (const platform of ["darwin", "darwin-x64", "darwin-arm64"]) {
for (let i = 0; i < 2; i++) {
const res = await fetch(
`${address}/electron/fiddle/${platform}/0.34.0`
);
t.equal(res.status, 200);

const body = await res.json();
t.match(body, {
name: "v0.35.1",
notes: "notes",
});
}
}
});

await t.test("not on Windows", async (t) => {
for (const platform of [
"win32",
"win32-x64",
"win32-ia32",
"win32-arm64",
]) {
for (let i = 0; i < 2; i++) {
const res = await fetch(
`${address}/electron/fiddle/${platform}/0.34.0`
);
t.equal(res.status, 200);

const body = await res.json();
t.match(body, {
name: "v0.36.0",
notes: "notes",
});
}
}
});
});

await t.test("updates to latest", async (t) => {
await t.test("on macOS", async (t) => {
for (const platform of ["darwin", "darwin-x64", "darwin-arm64"]) {
for (let i = 0; i < 2; i++) {
const res = await fetch(
`${address}/electron/fiddle/${platform}/0.35.1`
);
t.equal(res.status, 200);

const body = await res.json();
t.match(body, {
name: "v0.36.0",
notes: "notes",
});
}
}
});

await t.test("on Windows", async (t) => {
for (const platform of [
"win32",
"win32-x64",
"win32-ia32",
"win32-arm64",
]) {
for (let i = 0; i < 2; i++) {
const res = await fetch(
`${address}/electron/fiddle/${platform}/0.35.1`
);
t.equal(res.status, 200);

const body = await res.json();
t.match(body, {
name: "v0.36.0",
notes: "notes",
});
}
}
});
});

teardown(() => {
server.close();
});
});