mirror of
https://github.com/morluto/rea.git
synced 2026-10-26 17:35:11 +00:00
fix(release): support default credentials and record 5.0.0 boundary (#1012)
fix(release): support built-in credentials and refresh release boundary GitHub now creates approval-required PR workflows for GITHUB_TOKEN-authored opened/synchronize/reopened events. Restore optional custom credentials and cover prepare/publish without a separate secret. Record the verified 5.0.0 checkpoint, public 133-tool catalog and package update in the installation guide. Assisted-by: Sakuya (gensokyo-skills:sakuya-checkpointed-execution)
This commit is contained in:
1 parent
76e7e510bb
commit
6a278a68dd
4 files changed
+91
-49
No files matched your search
@@ -32,16 +32,6 @@ jobs:
|
||||
release_created: ${{ steps.release.outputs.release_created }}
|
||||
sha: ${{ steps.release.outputs.sha }}
|
||||
steps:
|
||||
- name: Require a CI-capable release token
|
||||
shell: bash
|
||||
env:
|
||||
RELEASE_PLEASE_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN }}
|
||||
run: |
|
||||
if [[ -z "${RELEASE_PLEASE_TOKEN}" ]]; then
|
||||
echo "RELEASE_PLEASE_TOKEN is required. Pull requests and catalog commits created with GITHUB_TOKEN do not start workflow runs, so the normalized release head would have no CI result to approve." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Validate release selection
|
||||
shell: bash
|
||||
env:
|
||||
@@ -97,9 +87,9 @@ jobs:
|
||||
- uses: googleapis/release-please-action@v4
|
||||
id: release
|
||||
with:
|
||||
# A dedicated credential lets release-PR updates trigger CI.
|
||||
# GITHUB_TOKEN-authored pull requests do not start workflow runs.
|
||||
token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
|
||||
# A dedicated credential starts PR CI automatically; the built-in
|
||||
# token creates approval-required PR runs for maintainers to approve.
|
||||
token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
target-branch: ${{ inputs.release_branch }}
|
||||
skip-github-release: ${{ inputs.phase == 'prepare' }}
|
||||
skip-github-pull-request: ${{ inputs.phase == 'publish' }}
|
||||
@@ -148,7 +138,7 @@ jobs:
|
||||
shell: bash
|
||||
env:
|
||||
# Use the same identity for the follow-up commit so it also triggers CI.
|
||||
GH_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
RELEASE_PR_JSON: ${{ steps.release.outputs.pr }}
|
||||
run: |
|
||||
release_pr_branch="$(node --input-type=module -e '
|
||||
|
||||
+12
-7
@@ -68,13 +68,18 @@ selects the npm release, and persistent MCP registrations are pinned to the
|
||||
version that performed setup. Installing newer instructions does not update a
|
||||
running server or its registration.
|
||||
|
||||
The release checked on **2026-10-06** was **4.1.0** (125 MCP tools). That artifact
|
||||
includes main's Windows native control bundle, Android/JADX and firmware
|
||||
tools, Ghidra function annotation workflow, and retained application-Evidence
|
||||
references.
|
||||
Main's catalog describes the current code; a source build or a subsequent
|
||||
release containing later changes is required for anything newer. Package startup alone does not verify a
|
||||
provider's real platform workflow.
|
||||
The release checked on **2026-10-07** was **5.0.0** (133 MCP tools), published
|
||||
from the fixed checkpoint
|
||||
[`b33236ec`](https://github.com/morluto/rea/releases/tag/rea-agents-5.0.0).
|
||||
The public CLI, MCP catalog and target-free session, and isolated update from
|
||||
4.1.0 to 5.0.0 were verified through npm. The artifact includes Windows native
|
||||
controls, Android/JADX and firmware tools, Ghidra function annotations, and
|
||||
retained application-Evidence references.
|
||||
|
||||
Main's catalog describes the current code. A source build or a subsequent
|
||||
release containing changes after this checkpoint is required for newer
|
||||
functionality. Package startup alone does not verify a provider's real
|
||||
platform workflow.
|
||||
|
||||
To check the published version, run `npm view rea-agents dist-tags.latest`.
|
||||
Use the connected server's actual tool list and advertised input schemas for
|
||||
|
||||
+12
-8
@@ -35,14 +35,18 @@ gh workflow run release.yml --ref main \
|
||||
```
|
||||
|
||||
Release Please targets that branch and prepares its version, changelog, and
|
||||
registry metadata. Preparation requires the `RELEASE_PLEASE_TOKEN` repository
|
||||
secret. That credential opens the release pull request and pushes the catalog
|
||||
normalization commit, so both start CI on the exact normalized head. The
|
||||
default `GITHUB_TOKEN` cannot do that: events it authors do not start
|
||||
workflow runs, and there is then no blocked run to approve. The existing
|
||||
generation step normalizes the product catalog. Preparation cannot create a
|
||||
GitHub release or publish a package. Record the final bot PR head after
|
||||
normalization and wait for that head's CI.
|
||||
registry metadata. The workflow uses an optional `RELEASE_PLEASE_TOKEN`
|
||||
repository secret and otherwise uses the built-in `GITHUB_TOKEN`. A dedicated
|
||||
GitHub App or personal access token can start PR CI automatically. With the
|
||||
built-in token, `opened`, `synchronize`, and `reopened` PR events create runs
|
||||
that require a maintainer with write access to approve them. See
|
||||
[GitHub's workflow trigger documentation](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/trigger-a-workflow).
|
||||
|
||||
The generation step normalizes the product catalog. Preparation cannot create
|
||||
a GitHub release or publish a package. Record the final bot PR head after
|
||||
normalization, then approve that head's blocked runs from the PR page. Updates
|
||||
to the bot branch can create new approval-required runs; approval of an older
|
||||
head does not verify the normalized candidate. Wait for the final head's CI.
|
||||
|
||||
Review the candidate's version, notes, generated metadata, and package
|
||||
contents. Wait for the candidate's CI and relevant real-provider checks.
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { execFile } from "node:child_process";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { readFile, writeFile } from "node:fs/promises";
|
||||
import { delimiter, join } from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
import { expect, it } from "vitest";
|
||||
import { parse } from "yaml";
|
||||
import { z } from "zod";
|
||||
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
|
||||
const execFileAsync = promisify(execFile);
|
||||
const stepSchema = z.object({
|
||||
name: z.string().optional(),
|
||||
@@ -58,7 +61,7 @@ it("requires explicit release preparation or publication instead of main pushes"
|
||||
step.uses?.startsWith("googleapis/release-please-action@"),
|
||||
);
|
||||
expect(release?.with).toMatchObject({
|
||||
token: "${{ secrets.RELEASE_PLEASE_TOKEN }}",
|
||||
token: "${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}",
|
||||
"target-branch": "${{ inputs.release_branch }}",
|
||||
"skip-github-release": "${{ inputs.phase == 'prepare' }}",
|
||||
"skip-github-pull-request": "${{ inputs.phase == 'publish' }}",
|
||||
@@ -67,28 +70,68 @@ it("requires explicit release preparation or publication instead of main pushes"
|
||||
(step) => step.name === "Commit canonical release catalog",
|
||||
);
|
||||
expect(catalogCommit?.env?.GH_TOKEN).toBe(
|
||||
"${{ secrets.RELEASE_PLEASE_TOKEN }}",
|
||||
"${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}",
|
||||
);
|
||||
});
|
||||
|
||||
it("stops preparation when the CI-capable release token is missing", async () => {
|
||||
const workflow = await readReleaseWorkflow();
|
||||
const command = z
|
||||
.string()
|
||||
.parse(
|
||||
workflow.jobs["release-please"].steps.find(
|
||||
(step) => step.name === "Require a CI-capable release token",
|
||||
)?.run,
|
||||
it.skipIf(process.platform === "win32").each([
|
||||
{ phase: "prepare", customToken: "" },
|
||||
{ phase: "publish", customToken: "" },
|
||||
{ phase: "prepare", customToken: "fixture-custom-token" },
|
||||
{ phase: "publish", customToken: "fixture-custom-token" },
|
||||
])(
|
||||
"accepts $phase with optional custom credentials: $customToken",
|
||||
async ({ phase, customToken }) => {
|
||||
const workflow = await readReleaseWorkflow();
|
||||
const steps = workflow.jobs["release-please"].steps;
|
||||
const actionIndex = steps.findIndex((step) =>
|
||||
step.uses?.startsWith("googleapis/release-please-action@"),
|
||||
);
|
||||
await expect(
|
||||
execFileAsync("bash", ["-e", "-o", "pipefail", "-c", command], {
|
||||
env: { ...process.env, RELEASE_PLEASE_TOKEN: "" },
|
||||
}),
|
||||
).rejects.toMatchObject({
|
||||
code: 1,
|
||||
stderr: expect.stringMatching(/RELEASE_PLEASE_TOKEN/u),
|
||||
});
|
||||
});
|
||||
expect(actionIndex).toBeGreaterThanOrEqual(0);
|
||||
const commands = steps
|
||||
.slice(0, actionIndex)
|
||||
.filter(
|
||||
(step) =>
|
||||
step.if === undefined ||
|
||||
(phase === "publish" && step.if === "inputs.phase == 'publish'"),
|
||||
)
|
||||
.map((step) => z.string().parse(step.run));
|
||||
const directory = await createTestTempDirectory("rea-release-credential-");
|
||||
const output = join(directory, "github-output");
|
||||
await writeFile(
|
||||
join(directory, "gh"),
|
||||
'#!/bin/sh\nprintf "%s\\n" "$GITHUB_SHA"\n',
|
||||
{ mode: 0o755 },
|
||||
);
|
||||
await expect(
|
||||
execFileAsync(
|
||||
"bash",
|
||||
["-e", "-o", "pipefail", "-c", commands.join("\n")],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
PATH: `${directory}${delimiter}${process.env.PATH ?? ""}`,
|
||||
RELEASE_PLEASE_TOKEN: customToken,
|
||||
GH_TOKEN: customToken || "fixture-built-in-token",
|
||||
RELEASE_PHASE: phase,
|
||||
RELEASE_BRANCH: "release/5.0.0",
|
||||
GITHUB_REF:
|
||||
phase === "prepare"
|
||||
? "refs/heads/main"
|
||||
: "refs/heads/release/5.0.0",
|
||||
GITHUB_REPOSITORY: "fixture/fixture",
|
||||
GITHUB_SHA: "1111111111111111111111111111111111111111",
|
||||
BRANCH_SHA: "1111111111111111111111111111111111111111",
|
||||
GITHUB_OUTPUT: output,
|
||||
},
|
||||
},
|
||||
),
|
||||
).resolves.toMatchObject({ stderr: "" });
|
||||
expect(await readFile(output, "utf8")).toBe(
|
||||
"sha=1111111111111111111111111111111111111111\n",
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
it("binds npm and MCP publication to the same immutable release SHA", async () => {
|
||||
const workflow = await readReleaseWorkflow();
|
||||
|
||||
Reference in new issue
Block a user