diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 00224b7..71ea18b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,12 +1,66 @@ name: CI on: + workflow_call: push: branches: [ master, main ] pull_request: branches: [ master, main ] jobs: + console: + name: Public console build and browser regression + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '24' + cache: npm + cache-dependency-path: web/package-lock.json + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache-dependency-path: | + go.sum + api/go.sum + - name: Verify public source reproduces embedded assets + run: bash scripts/sync-ui.sh --check + - name: Audit complete console dependency tree + run: npm audit --prefix web + - name: Start disposable MongoDB replica set + run: | + docker run -d --name console-mongo -p 127.0.0.1:27017:27017 mongo:7.0.43 --replSet rs0 --bind_ip_all + for i in $(seq 1 30); do docker exec console-mongo mongosh --quiet --eval 'db.adminCommand({ping:1})' && break; sleep 1; done + docker exec console-mongo mongosh --quiet --eval 'rs.initiate({_id:"rs0",members:[{_id:0,host:"localhost:27017"}]})' + for i in $(seq 1 30); do docker exec console-mongo mongosh --quiet --eval 'if(!db.hello().isWritablePrimary)quit(1)' && break; sleep 1; done + docker exec console-mongo mongosh --quiet --eval 'if(!db.hello().isWritablePrimary)quit(1)' + - name: Build the same engine commit with embedded UI + working-directory: api + run: go build -o /tmp/argon-console-api . + - name: Start production console in isolated demo mode + run: | + PORT=18081 ARGON_DEMO_MODE=1 ARGON_METADATA_DB=argon_console_ci /tmp/argon-console-api >/tmp/argon-console-engine.log 2>&1 & + for i in $(seq 1 30); do curl --fail --silent http://127.0.0.1:18081/api/v1/meta >/dev/null && break; sleep 1; done + curl --fail --silent http://127.0.0.1:18081/api/v1/meta + - name: Install browser + working-directory: web + run: npx playwright install --with-deps chromium + - name: Verify Undo, recovery, conflict review and responsive UI + working-directory: web + env: + CONSOLE_URL: http://127.0.0.1:18081 + run: npm run test:browser + - uses: actions/upload-artifact@v4 + if: always() + continue-on-error: true # Optional evidence; the browser/build steps remain required. + with: + name: public-console-evidence + path: | + /tmp/argon-console-checks + /tmp/argon-console-engine.log + test: name: Test runs-on: ubuntu-latest @@ -47,6 +101,9 @@ jobs: - name: Download dependencies run: go mod download + - name: Compile an external Go v2 consumer + run: bash scripts/check-go-module.sh + - uses: actions/setup-node@v4 with: node-version: '22' @@ -61,7 +118,7 @@ jobs: run: | docker run -d --name ci-minio -p 9010:9000 \ -e MINIO_ROOT_USER=argon -e MINIO_ROOT_PASSWORD=argon12345 \ - minio/minio server /data + quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e server /data for i in $(seq 1 30); do curl -sf http://localhost:9010/minio/health/live && break sleep 1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 242c795..dc3d3ce 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,6 +12,10 @@ concurrency: cancel-in-progress: false jobs: + validate: + name: Validate the tagged source + uses: ./.github/workflows/ci.yml + prepare: name: Validate release version runs-on: ubuntu-latest @@ -19,6 +23,8 @@ jobs: version: ${{ steps.version.outputs.version }} steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 - uses: actions/setup-node@v4 with: node-version: '22' @@ -27,67 +33,55 @@ jobs: env: RELEASE_TAG: ${{ github.ref_name }} run: | - version=$(node scripts/release-version.js "$RELEASE_TAG") + version=$(node scripts/release-version.js "$RELEASE_TAG" --check) echo "version=$version" >> "$GITHUB_OUTPUT" - node scripts/release-version.js --check + # Nested Go modules need their own semantic-version tag. Both tags + # must identify the reviewed source that the reusable CI validates. + test "$(git rev-parse "refs/tags/api/v${version}^{commit}")" = "$(git rev-parse HEAD)" - name: Check release tooling run: node --test scripts/release-version.test.js npm/scripts/install.test.js - build: - name: Build binaries - needs: prepare + release: + name: Build and publish verified binaries + needs: [prepare, validate] runs-on: ubuntu-latest - strategy: - matrix: - goos: [linux, darwin, windows] - goarch: [amd64, arm64] - exclude: - - goos: windows - goarch: arm64 + permissions: + contents: write steps: - uses: actions/checkout@v4 - - name: Set up Go - uses: actions/setup-go@v5 + - uses: actions/setup-node@v4 + with: + node-version: '24' + - uses: actions/setup-go@v5 with: go-version-file: go.mod cache-dependency-path: | go.sum cli/go.sum api/go.sum - - name: Build binary + # Cross-compile in one job. Final release assets are uploaded directly; + # publication does not depend on temporary Actions artifact storage. + - name: Build every supported platform working-directory: cli env: - GOOS: ${{ matrix.goos }} - GOARCH: ${{ matrix.goarch }} CGO_ENABLED: '0' RELEASE_VERSION: ${{ needs.prepare.outputs.version }} run: | mkdir -p ../dist - asset="argon-${GOOS}-${GOARCH}" - if [ "$GOOS" = windows ]; then asset="$asset.exe"; fi - go build -trimpath -ldflags="-s -w -X github.com/argon-lab/argon/pkg/version.Build=$RELEASE_VERSION" -o "../dist/$asset" . - - uses: actions/upload-artifact@v4 - with: - name: binaries-${{ matrix.goos }}-${{ matrix.goarch }} - path: dist/ - if-no-files-found: error - - release: - name: Create release - needs: [prepare, build] - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - uses: actions/download-artifact@v4 - with: - pattern: binaries-* - path: dist/ - merge-multiple: true + for target in linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64; do + export GOOS="${target%/*}" GOARCH="${target#*/}" + asset="argon-${GOOS}-${GOARCH}" + if [ "$GOOS" = windows ]; then asset="$asset.exe"; fi + go build -trimpath -ldflags="-s -w -X github.com/argon-lab/argon/v2/pkg/version.Build=$RELEASE_VERSION" -o "../dist/$asset" . + done + - name: Record engine, public console and binary provenance + env: + RELEASE_VERSION: ${{ needs.prepare.outputs.version }} + run: node scripts/release-provenance.mjs dist - name: Generate checksums working-directory: dist - run: sha256sum argon-* > SHA256SUMS - - name: Create release + run: sha256sum argon-* release-provenance.json > SHA256SUMS + - name: Create release with all required assets uses: softprops/action-gh-release@v2 with: files: dist/* diff --git a/CHANGELOG.md b/CHANGELOG.md index 94cdf0b..b37f926 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,41 @@ Planned: GCS chunk-store backend; an opt-in read-your-writes barrier in the wire proxy (hold a write's ack until the ingester confirms the WAL entry — a synchronization barrier, not in-proxy capture). +## [2.1.2] - 2026-09-24 + +### Fixed + +- REST branch creation drains the live parent's capture before fixing its fork + point and refuses degraded history; omitted `from` defaults to `main`. +- Concurrent engine/CLI startup preserves the current unique WAL index instead + of dropping and rebuilding it on every connection. Legacy definitions still + migrate when needed. +- Canceling capture while enabling images for a new collection preserves the + resumable boundary and stops cleanly instead of marking a permanent history gap. +- Go consumers use valid `github.com/argon-lab/argon/v2` and + `github.com/argon-lab/argon/api/v2` modules, with separate matching release tags. +- Console Undo applies the exact actor and bounded LSN range just reviewed; + changing scope invalidates review, including delayed preview responses. +- Expired/reset demo sessions offer a fresh start, clear stale queries and + recover old deep links. Late old-session failures cannot end a renewed session. + +### Import and release hardening + +- Real imports require `--source-quiesced`: stop source writes and DDL for the + entire copy. Preflight rejects unreadable/unsupported collections before + creating target data. Imports remain hidden until successful completion. +- Failed or canceled imports remove their unpublished project/history so the + name can be retried. `argon import cleanup --project P --yes` recovers an + unfinished import after a killed process; completed projects are protected. +- Release publication depends on the complete CI suite for the exact tagged + source, consistent committed version metadata and matching root/API tags. + CI also compiles an external Go consumer of both v2 modules. +- The MIT console source is public in `web/`. Locked builds reproduce the + embedded assets; browser regressions run against the same engine commit. + Release provenance records engine/UI source and every binary checksum. +- Publishing and performance documentation now describes the actual release + flow, source-quiescence contract and completed small-scale benchmark evidence. + ## [2.1.1] - 2026-09-07 ### Fixed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 09cfab3..7c8f629 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -39,9 +39,9 @@ Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md) to ensure a wel ### Prerequisites -- Go 1.21+ +- Go 1.26.6+ (see `go.mod`) - Docker (for MongoDB and MinIO) -- Node 20+ and Python 3.10+ only if you touch the driver-compatibility +- Node.js 24 for the console (`web/`); Python 3.10+ for the driver-compatibility harness (`compat/`) ### MongoDB (replica set required) @@ -70,11 +70,13 @@ golangci-lint run ./... # run in each module you touched The S3 chunk-store tests are gated: they skip unless `ARGON_TEST_S3_ENDPOINT` / `ARGON_TEST_S3_BUCKET` (plus `AWS_*` -credentials) point at an S3-compatible store. Locally, MinIO works: +credentials) point at an S3-compatible store. For a disposable local test fixture, use the pinned historical MinIO image +below. It is not a production storage recommendation; community binaries are +[no longer maintained](https://github.com/minio/minio#source-only-distribution). ```bash docker run -d --name argon-minio -p 9010:9000 \ - -e MINIO_ROOT_USER=argon -e MINIO_ROOT_PASSWORD=argon12345 minio/minio server /data + -e MINIO_ROOT_USER=argon -e MINIO_ROOT_PASSWORD=argon12345 quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z server /data ARGON_TEST_S3_ENDPOINT=http://localhost:9010 ARGON_TEST_S3_BUCKET=argon-test \ AWS_ACCESS_KEY_ID=argon AWS_SECRET_ACCESS_KEY=argon12345 AWS_REGION=us-east-1 \ go test ./tests/wal/ -run TestChunkStore -count=1 @@ -84,6 +86,15 @@ The driver-compatibility harness (`bash compat/run.sh`) runs real pymongo and mongoose workloads against a checked-out branch and verifies WAL convergence; CI runs it on every push. +### Console source and reproducible assets + +The current console is public in [`web/`](web/README.md), under MIT. Run +`bash scripts/sync-ui.sh` from this repository to rebuild the assets embedded +in the Go binary. `bash scripts/sync-ui.sh --check` verifies the committed +assets and their SHA-256 provenance. Commit source and built assets together. +No private companion checkout is needed. CI tests the production console +against the same engine commit, including Undo scope and expired sessions. + ### Two rules the tests enforce - **Determinism**: replaying the same WAL prefix must always produce the @@ -139,9 +150,10 @@ convergence; CI runs it on every push. ### Before Submitting -- [ ] Run `make lint` to check code style -- [ ] Run `make test` to ensure all tests pass -- [ ] Run `make bench` if you've made performance-related changes +- [ ] Run `go vet ./...` in each changed Go module +- [ ] Run the engine, API and CLI tests described above +- [ ] Run `bash scripts/sync-ui.sh --check` for console changes +- [ ] Use the [benchmark suite](https://github.com/argon-lab/benchmarks) for performance claims - [ ] Update documentation for API changes - [ ] Add tests for new functionality - [ ] Rebase on latest main branch @@ -305,10 +317,10 @@ We value all contributions! Contributors will be: export ARGON_LOG_LEVEL=debug # Run with race detector -go run -race ./cmd/argon +(cd cli && go run -race . console --no-browser) -# Profile CPU usage -go run ./cmd/argon --cpuprofile=cpu.prof +# Profile engine tests +go test ./tests/wal -run Test -cpuprofile=cpu.prof ``` ### Common Issues @@ -321,7 +333,7 @@ go run ./cmd/argon --cpuprofile=cpu.prof ```bash # Run specific tests -go test -run TestBranchCreation ./engine +go test ./tests/wal -run TestBranch -count=1 # Update all dependencies go get -u ./... diff --git a/README.md b/README.md index 4bdc4a9..7320a2a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Argon — Git for MongoDB
-
+