Skip to content
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
10 changes: 10 additions & 0 deletions .github/scripts/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# CI Helpers

## Crabbox hydration

The hydration workflow writes lease-scoped `<id>.env` and `<id>.env.sh` files
under `~/.crabbox/actions` and watches `<id>.stop`, matching the Crabbox CLI.
The job name is metadata inside the readiness marker, not part of these paths.
Keep the Go setup inputs compatible with Crabbox's local Actions adapter; its
`setup-go` support does not accept an explicit `cache` input.
`crabbox-hydrate.test.cjs` executes the workflow's shell steps with a temporary
home to verify readiness discovery and immediate shutdown on the stop signal.

`downstream-compat.sh` compares the complete Gitcrawl CLI test suite against a
pinned Crawlkit baseline and the candidate checkout. The source pins live in
`ci.yml`. Update pins deliberately, with exact-head review.
Expand Down
63 changes: 63 additions & 0 deletions .github/scripts/crabbox-hydrate.test.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const assert = require('node:assert/strict');
const { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } = require('node:fs');
const { tmpdir } = require('node:os');
const { join } = require('node:path');
const { spawnSync } = require('node:child_process');
const { test } = require('node:test');

const workflow = readFileSync(join(__dirname, '../workflows/crabbox-hydrate.yml'), 'utf8');

function runStep(name) {
const lines = workflow.split('\n');
const step = lines.indexOf(` - name: ${name}`);
assert.notEqual(step, -1, `missing workflow step: ${name}`);
const start = lines.findIndex((line, index) => index > step && line === ' run: |');
assert.notEqual(start, -1, `missing shell script: ${name}`);
const script = [];
for (const line of lines.slice(start + 1)) {
if (line && !line.startsWith(' ')) break;
script.push(line.slice(10));
}
return script.join('\n');
}

function fixture(t) {
const home = mkdtempSync(join(tmpdir(), 'crawlkit-hydrate-'));
t.after(() => rmSync(home, { recursive: true, force: true }));
const env = {
PATH: process.env.PATH,
HOME: home,
CRABBOX_ID: 'cbx_test123',
CRABBOX_JOB: 'hydrate',
CRABBOX_KEEP_ALIVE_MINUTES: '90',
GITHUB_WORKSPACE: join(home, 'workspace'),
GITHUB_SHA: 'a'.repeat(40),
GITHUB_RUN_ID: '123',
};
return { home, env, actions: join(home, '.crabbox/actions') };
}

test('hydration publishes the lease-scoped marker and environment used by Crabbox', (t) => {
const { home, env, actions } = fixture(t);
const result = spawnSync('bash', ['-c', runStep('Mark Crabbox ready')], { env, encoding: 'utf8' });
assert.equal(result.status, 0, result.stderr);
const marker = readFileSync(join(actions, 'cbx_test123.env'), 'utf8');
assert.match(marker, /^JOB=hydrate$/m);
assert.match(marker, /^RUN_ID=123$/m);
assert.ok(marker.includes(`WORKSPACE=${join(home, 'workspace')}\n`));
assert.ok(marker.includes(`ENV_FILE=${join(actions, 'cbx_test123.env.sh')}\n`));
assert.match(readFileSync(join(actions, 'cbx_test123.env.sh'), 'utf8'), /^export GITHUB_SHA=/m);
});

test('the lease-scoped stop signal ends the hydration job immediately', (t) => {
const { home, env, actions } = fixture(t);
mkdirSync(actions, { recursive: true });
writeFileSync(join(actions, 'cbx_test123.stop'), '');
const bin = join(home, 'bin');
mkdirSync(bin);
// A missed stop signal must fail promptly instead of sleeping for 90 minutes.
writeFileSync(join(bin, 'sleep'), '#!/bin/sh\nexit 42\n', { mode: 0o755 });
env.PATH = `${bin}:${env.PATH}`;
const result = spawnSync('bash', ['-c', runStep('Keep Crabbox job alive')], { env, encoding: 'utf8' });
assert.equal(result.status, 0, result.stderr);
});
5 changes: 2 additions & 3 deletions .github/workflows/crabbox-hydrate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ jobs:
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: true

- name: Prepare Go workspace
shell: bash
Expand Down Expand Up @@ -74,7 +73,7 @@ jobs:
;;
esac
mkdir -p "$HOME/.crabbox/actions"
key="${CRABBOX_ID}.${job}"
key="${CRABBOX_ID}"
state="$HOME/.crabbox/actions/${key}.env"
env_file="$HOME/.crabbox/actions/${key}.env.sh"
{
Expand Down Expand Up @@ -122,7 +121,7 @@ jobs:
case "$minutes" in
''|*[!0-9]*) minutes=90 ;;
esac
stop="$HOME/.crabbox/actions/${CRABBOX_ID}.${job}.stop"
stop="$HOME/.crabbox/actions/${CRABBOX_ID}.stop"
deadline=$(( $(date +%s) + minutes * 60 ))
while [ "$(date +%s)" -lt "$deadline" ]; do
if [ -f "$stop" ]; then
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

- Fix Crabbox hydration readiness and shutdown with lease-scoped state files, and allow automatic local hydration by omitting an unsupported explicit cache option.
- Update SQLite's indirect pprof test dependency to the October 16 revision while preserving the required SQLite/libc version pair and Go 1.27.0 minimum.
- Refresh pprof, Go analysis tooling, and the pinned TruffleHog action while retaining the Go 1.27.0 minimum and SQLite's required libc version.
- Add an explicit release-workflow dry run to validate signed builds without creating a tag or publishing a release; preserve the existing-version guard for real releases.

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ require (
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
github.com/dustin/go-humanize v1.1.0 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/google/pprof v0.0.0-20261014150452-c3b4e57cab2c // indirect
github.com/google/pprof v0.0.0-20261016150608-1facf8f91b50 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/lucasb-eyer/go-colorful v1.4.1 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ github.com/dustin/go-humanize v1.1.0 h1:dbKTrvD0klcbBV/h4AWJdMuZogJACoMlvWIWZ5b2
github.com/dustin/go-humanize v1.1.0/go.mod h1:hc1CvRkJMsgxqjmjMQF3QNRAZBwY8AXBAzKYoSX9sFI=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/google/pprof v0.0.0-20261014150452-c3b4e57cab2c h1:h/rBeOCBnD/SNCvq6FHunZaiCYqpbhx3FyGcVtpLaIE=
github.com/google/pprof v0.0.0-20261014150452-c3b4e57cab2c/go.mod h1:yUo1AMMpsPIDFGuwDK8nLcf8+vvAd5l2O6JDZ6hpwrM=
github.com/google/pprof v0.0.0-20261016150608-1facf8f91b50 h1:PlNWJRxu5APSV0pWqfIsZ0qt9OOGHSWfZQ4zvx+WgWs=
github.com/google/pprof v0.0.0-20261016150608-1facf8f91b50/go.mod h1:yUo1AMMpsPIDFGuwDK8nLcf8+vvAd5l2O6JDZ6hpwrM=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
Expand Down
Loading