Two-node VM test for forge-sync: clone, open a PR, be refused on master #140

Closed
opened 2026-10-08 05:19:22 +01:00 by vnprc-agent · 1 comment

forge-sync (allod/nexus#84) is the command that makes a forge VM usable, and the repository it lives in has no NixOS test harness — only shell tests. This is its executable witness: a two-node test where the command runs against a real Forgejo and a dev-shaped client does the thing the whole arc exists for.

Primary goals:

  • A client that looks like a dev VM — git, ssh and the forge CLI, and deliberately no git hooks, so a refusal comes from the server rather than from a local policy hook.
  • The round trip — the client clones over the clone port, pushes a branch, opens a pull request with forge pr create, and reads it back through the API.
  • The server refuses master — a push to master fails with Forgejo's own pre-receive message, with the client's hook absent, so what is witnessed is branch protection and not a hook.
  • Protection is readable back — the API lists the rule the policy file declares.
  • The token appears in no log — the driver log, both machines' journals, and the test's output store path are grepped for the minted token and it is absent.

Current state and specifics

This repository already has the harness and the node shape. checks/forgejo.nix is slice 1's two-node test (forge, client) with the forge in fresh, plain-http mode, clone on 2222 and administrative ssh on 22; it already demonstrates the two idioms this test needs — a curl config on stdin so no credential is ever an argument, and a token transported as a copied file rather than a command line. checks/service-vm.nix is the newer example of composing serviceModules directly rather than reimplementing production.

Two mechanics worth knowing before starting, both measured: a NixOS VM test's $out keeps no driver log, and extraDriverArgs = [ "--junit-xml" "junit.xml" ] produces one including serial consoles — which is what makes the token-absence grep possible at all; and the kernel prints 40-hex certificate fingerprints into that log, so a "no token-shaped string" grep must skip ^<machine> # lines or it will match them.

This repository consumes allod/nexus as an input, and nexus-provisioning-scripts copies scripts/ out of the whole flake source path, so the command under test is reachable from here.

Scope

In: the test, and whatever parameterisation of the command it needs to be driven from a test driver rather than an operator's terminal — note allod/nexus#84 gives it a --user flag for exactly this reason, so no interactive prompt blocks the driver. Out: the command itself, and anything that would make the command aware it is under test — a fixture flag or an isTest branch on a path that handles a token as root is the contamination testing.md forbids.

Part of allod/strategy#65

`forge-sync` (allod/nexus#84) is the command that makes a forge VM usable, and the repository it lives in has no NixOS test harness — only shell tests. This is its executable witness: a two-node test where the command runs against a real Forgejo and a dev-shaped client does the thing the whole arc exists for. Primary goals: - **A client that looks like a dev VM** — git, ssh and the `forge` CLI, and deliberately no git hooks, so a refusal comes from the server rather than from a local policy hook. - **The round trip** — the client clones over the clone port, pushes a branch, opens a pull request with `forge pr create`, and reads it back through the API. - **The server refuses master** — a push to master fails with Forgejo's own pre-receive message, with the client's hook absent, so what is witnessed is branch protection and not a hook. - **Protection is readable back** — the API lists the rule the policy file declares. - **The token appears in no log** — the driver log, both machines' journals, and the test's output store path are grepped for the minted token and it is absent. ### Current state and specifics This repository already has the harness and the node shape. `checks/forgejo.nix` is slice 1's two-node test (`forge`, `client`) with the forge in fresh, plain-http mode, clone on 2222 and administrative ssh on 22; it already demonstrates the two idioms this test needs — a `curl` config on stdin so no credential is ever an argument, and a token transported as a copied file rather than a command line. `checks/service-vm.nix` is the newer example of composing `serviceModules` directly rather than reimplementing production. Two mechanics worth knowing before starting, both measured: a NixOS VM test's `$out` keeps no driver log, and `extraDriverArgs = [ "--junit-xml" "junit.xml" ]` produces one including serial consoles — which is what makes the token-absence grep possible at all; and the kernel prints 40-hex certificate fingerprints into that log, so a "no token-shaped string" grep must skip `^<machine> # ` lines or it will match them. This repository consumes `allod/nexus` as an input, and `nexus-provisioning-scripts` copies `scripts/` out of the whole flake source path, so the command under test is reachable from here. ### Scope In: the test, and whatever parameterisation of the command it needs to be driven from a test driver rather than an operator's terminal — note allod/nexus#84 gives it a `--user` flag for exactly this reason, so no interactive prompt blocks the driver. Out: the command itself, and anything that would make the command aware it is under test — a fixture flag or an `isTest` branch on a path that handles a token as root is the contamination `testing.md` forbids. Part of allod/strategy#65
Author

Landed on master as 03f4d4d. Its nexus pin bump is a follow-up, since the check calls forge-sync which landed after the pin was taken.

Landed on master as 03f4d4d. Its `nexus` pin bump is a follow-up, since the check calls `forge-sync` which landed after the pin was taken.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
allod/archetypes#140
No description provided.