-
Notifications
You must be signed in to change notification settings - Fork 56
Releases: POST /releases/sync for the upload script #83
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| import { Request, Response } from "express"; | ||
| import { prisma } from "./db"; | ||
| import { BadRequestError, InternalServerError, NotFoundError } from "./errors"; | ||
| import { BadRequestError, ConflictError, InternalServerError, NotFoundError } from "./errors"; | ||
| import type { ReleaseSyncRunner } from "./release-sync"; | ||
| import semver from "semver"; | ||
|
|
||
| import { GetObjectCommand, ListObjectsV2Command } from "@aws-sdk/client-s3"; | ||
|
|
@@ -710,3 +711,19 @@ function latestArtifactRedirect(kind: OtaKind) { | |
| } | ||
|
|
||
| export const RetrieveLatestApp = latestArtifactRedirect("app"); | ||
|
|
||
| /** | ||
| * POST /releases/sync: register every stable R2 version missing from the DB | ||
| * and answer with the per-outcome counts. Made for the upload script's last | ||
| * step, so the settle window is off: the caller vouches its last object is | ||
| * written. | ||
| */ | ||
| export function Sync(runner: ReleaseSyncRunner) { | ||
| return async (req: Request, res: Response) => { | ||
| const stats = await runner({ uploadSettleMs: 0 }); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When another firmware version or type is still being uploaded, a POST made after an independent upload completes performs a bucket-wide scan with the settle window disabled. It can therefore persist the other upload's partial SKU set or stale hash, and Useful? React with 👍 / 👎.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed in #84: the body names the version the caller finished, and only that version skips the settle window. Every other version keeps it. |
||
| if (stats === "busy") { | ||
| throw new ConflictError("A release sync is already in progress"); | ||
| } | ||
| return res.json(stats); | ||
| }; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import type { Request, Response } from "express"; | ||
| import { describe, expect, it, vi } from "vitest"; | ||
|
|
||
| import { bearerToken } from "../src/auth"; | ||
| import { UnauthorizedError } from "../src/errors"; | ||
|
|
||
| describe("bearerToken", () => { | ||
| const guard = bearerToken("release-sync-secret"); | ||
| const res = {} as Response; | ||
|
|
||
| function request(authorization?: string): Request { | ||
| return { headers: { authorization } } as unknown as Request; | ||
| } | ||
|
|
||
| it("calls next for the configured token", () => { | ||
| const next = vi.fn(); | ||
| guard(request("Bearer release-sync-secret"), res, next); | ||
| expect(next).toHaveBeenCalledOnce(); | ||
| }); | ||
|
|
||
| it.each([ | ||
| ["no header", undefined], | ||
| ["wrong token", "Bearer nope"], | ||
| ["missing scheme", "release-sync-secret"], | ||
| ["prefix of the token", "Bearer release-sync"], | ||
| ])("rejects %s without calling next", (_label, authorization) => { | ||
| const next = vi.fn(); | ||
| expect(() => guard(request(authorization), res, next)).toThrow(UnauthorizedError); | ||
| expect(next).not.toHaveBeenCalled(); | ||
| }); | ||
| }); |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in #85: the scheme is matched case-insensitively with one or more spaces, and the token is still compared exactly.