cli: row 199 rotate on a due gitea key; ISSUED names rotation-due, the state the bus's status() gives a gitea key past its rotate-by date, so credentials rotate no longer refuses it; a test over every status state; BUILD.md deviation 15 (gizmoduck-0050, sage-1494, #1697)
This commit is contained in:
@@ -107,6 +107,13 @@ this branch, apart from one slip noted under "Runs".
|
||||
refuses `ref-moved` with no request to the fork; a push recorded while the bus process pushes
|
||||
refuses `decision-mismatch`, filed once, and the fork holds only the ticket's oid.
|
||||
|
||||
15. **Fix: rotate on a due gitea key (gizmoduck-0050, sage-1494).** The CLI's `ISSUED` set
|
||||
(`packages/cli/src/credentials.mjs`) listed valid, expiring and expired, but the bus's `status()`
|
||||
gives a gitea key past its rotate-by date `rotation-due`. So `credentials rotate` refused the one
|
||||
case it exists for. `ISSUED` now names every state status() gives a held token. The test:
|
||||
`cli/tests/credentials.test.mjs`, "rotate goes ahead on each held state". Its mutant (the old set)
|
||||
fails that test and goes in the section 11 list.
|
||||
|
||||
## N9, for the routing commit (sage-1388)
|
||||
|
||||
Today git.push.remote is a hard wait, so every publish carries a decision, and the decision's
|
||||
@@ -152,6 +159,9 @@ Hash pins: none on a changed file.
|
||||
sage-1440 changes (the poll bound, the mid-flight tests), single files, green before the commit: cli
|
||||
publish-socket (7), git-socket (24), launcher (29). Hash pins: none on a changed file.
|
||||
|
||||
The rotation-due fix, single files: cli credentials (4), green; the old-set mutant fails it 3/1.
|
||||
Hash pins: none on a changed file.
|
||||
|
||||
Slip, 2026-10-20 about 19:51Z: I ran `node --test packages/tasks/tests/*.test.mjs` in one command,
|
||||
which is a package suite, without asking Sage for the slot. It passed, 97 pass and 0 fail, in under a
|
||||
minute. Reported to Sage in megavolt-0017.
|
||||
|
||||
@@ -34,7 +34,9 @@ async function readToken(stdin) {
|
||||
return text;
|
||||
}
|
||||
|
||||
const ISSUED = new Set(["valid", "expiring", "expired"]);
|
||||
// The states the bus's status() gives a held token: gitea is valid or rotation-due, vikunja valid,
|
||||
// expiring or expired. not-issued and revoked hold none.
|
||||
const ISSUED = new Set(["valid", "rotation-due", "expiring", "expired"]);
|
||||
|
||||
export async function credentialsCommand(args, io, callFor) {
|
||||
const parsed = parse(args);
|
||||
|
||||
@@ -17,10 +17,10 @@ const ROWS = [
|
||||
{ service: "gitea", account: null, role: "reviewer", dateKind: "rotateBy", date: "2099-01-01", state: "revoked" },
|
||||
];
|
||||
|
||||
function deps(calls) {
|
||||
function deps(calls, rows = ROWS) {
|
||||
const answer = (who) => (business) => async (verb, args) => {
|
||||
calls.push({ who, business, verb, args });
|
||||
if (verb === "credentials") return ROWS;
|
||||
if (verb === "credentials") return rows;
|
||||
if (verb === "credentials.issue") return { agent: args.agent, verb: "issue", service: args.service, date: args.date, state: "valid" };
|
||||
return { agent: args.agent, verb: verb.slice(12), services: [] };
|
||||
};
|
||||
@@ -57,6 +57,23 @@ test("row 199: issue and rotate send the stdin token once to credentials.issue a
|
||||
await assert.rejects(main(["credentials", "issue", "coder", "gitea", "--rotate-by", "2099-01-01", "--business", "acme"], withStdin(io({ CLAUDECODE: "1" }), TOKEN), d), /outside any agent run/);
|
||||
});
|
||||
|
||||
// gizmoduck-0050: a gitea key past its rotate-by date is rotation-due, and rotate is how a human
|
||||
// clears it. Every state the bus's status() gives a held token rotates; the other two refuse.
|
||||
test("row 199: rotate goes ahead on each held state, rotation-due included, and refuses not-issued, revoked and an unknown entry", async () => {
|
||||
const states = { valid: true, "rotation-due": true, expiring: true, expired: true, "not-issued": false, revoked: false };
|
||||
for (const [state, held] of Object.entries(states)) {
|
||||
const calls = [];
|
||||
const d = deps(calls, [{ service: "gitea", account: null, role: "coder", dateKind: "rotateBy", date: "2020-01-01", state }]);
|
||||
const run = main(["credentials", "rotate", "coder", "gitea", "--rotate-by", "2099-06-01", "--business", "acme"], withStdin(io(), TOKEN), d);
|
||||
if (held) await run;
|
||||
else await assert.rejects(run, /no issued gitea credential to rotate; use issue/);
|
||||
assert.deepEqual(calls.map((c) => c.verb), held ? ["credentials", "credentials.issue"] : ["credentials"], state);
|
||||
}
|
||||
const calls = [];
|
||||
await assert.rejects(main(["credentials", "rotate", "tester", "gitea", "--rotate-by", "2099-06-01", "--business", "acme"], withStdin(io(), TOKEN), deps(calls)), /no issued gitea credential/);
|
||||
assert.deepEqual(calls.map((c) => c.verb), ["credentials"]);
|
||||
});
|
||||
|
||||
test("row 199: status, revoke and delete; the tester runs status and revoke only", async () => {
|
||||
const calls = [];
|
||||
const d = deps(calls);
|
||||
|
||||
Reference in New Issue
Block a user