diff --git a/.forgejo/workflows/ci-smoke.yaml b/.forgejo/workflows/ci-smoke.yaml new file mode 100644 index 0000000..bd44c56 --- /dev/null +++ b/.forgejo/workflows/ci-smoke.yaml @@ -0,0 +1,29 @@ +# Canonical CI smoke template (tier 1 routing drill). +# Copy to: .forgejo/workflows/ci-smoke.yaml in consumer repos. +name: CI Smoke + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + host-smoke: + runs-on: self-hosted + steps: + - name: Routing probe (host runner) + run: | + set -eu + echo "repository=${GITHUB_REPOSITORY:-unknown}" + echo "sha=${GITHUB_SHA:-unknown}" + echo "runner=${RUNNER_NAME:-unknown}" + uname -a + + container-smoke: + runs-on: ubuntu-latest + steps: + - name: Routing probe (container label) + run: | + set -eu + echo "container-smoke ok for ${GITHUB_REPOSITORY:-unknown}" \ No newline at end of file diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml new file mode 100644 index 0000000..cc9d5bf --- /dev/null +++ b/.forgejo/workflows/ci.yml @@ -0,0 +1,77 @@ +# Ported from .gitea/workflows/ci.yml (REUSE-WP-0019-T03). No actions/checkout +# on this runner substrate (railiance-enablement/docs/forgejo-actions-workflow-templates.md) +# -- ubuntu-latest maps to docker://node:20-bookworm, no Python preinstalled, +# so use archive checkout + apt. +name: ci + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: + +jobs: + validate-registry: + runs-on: ubuntu-latest + steps: + - name: Archive checkout + run: | + set -eu + REF="${GITHUB_SHA:-main}" + SHORT="${REF:0:7}" + mkdir -p /tmp/repo + wget -qO /tmp/repo.tar.gz "https://forgejo.coulomb.social/${GITHUB_REPOSITORY}/archive/${SHORT}.tar.gz" + tar xzf /tmp/repo.tar.gz -C /tmp/repo --strip-components=1 + + - name: Install Python + package + working-directory: /tmp/repo + run: | + set -eu + apt-get update -qq + apt-get install -y -qq python3 python3-pip python3-venv >/dev/null + python3 -m pip install --break-system-packages -e ".[dev]" + + - name: Validate capability registry + working-directory: /tmp/repo + run: reuse-surface validate --relations --fail-on-warnings + + - name: Compose federated index + working-directory: /tmp/repo + run: reuse-surface federation compose + + - name: Generate catalog and graph + working-directory: /tmp/repo + run: | + reuse-surface catalog + reuse-surface graph --check --fail-on-warnings + + - name: Registry maintain dry-run (informational) + working-directory: /tmp/repo + run: reuse-surface maintain --all --auto --no-llm || true + + - name: Registry stats (informational) + working-directory: /tmp/repo + run: reuse-surface stats || true + + - name: Workstation roster federation stats (informational) + working-directory: /tmp/repo + run: | + reuse-surface stats --roster registry/federation/local-repo-roster.yaml \ + --federation-ready --format json || true + + - name: Planning cohort report (informational) + working-directory: /tmp/repo + run: reuse-surface report cohorts --planning-min D4 || true + + - name: Registry gap report (informational) + working-directory: /tmp/repo + run: reuse-surface report gaps || true + + - name: Plan-check smoke test (informational) + working-directory: /tmp/repo + run: reuse-surface plan-check --intent "smoke test" --format json || true + + - name: Run tests + working-directory: /tmp/repo + run: pytest -q diff --git a/.forgejo/workflows/image.yaml b/.forgejo/workflows/image.yaml new file mode 100644 index 0000000..6dd7329 --- /dev/null +++ b/.forgejo/workflows/image.yaml @@ -0,0 +1,46 @@ +# Canonical single-repo image build template (railiance-enablement/workflows/container-build-push.yaml). +# Requires org secrets: REGISTRY_USER, REGISTRY_TOKEN +name: Build and Publish Container Image + +on: + push: + branches: + - main + paths: + - ".forgejo/workflows/image.yaml" + - "Dockerfile" + - "reuse_surface/**" + - "schemas/**" + - "pyproject.toml" + workflow_dispatch: + +env: + REGISTRY: forgejo.coulomb.social + IMAGE_NAME: coulomb/reuse-surface + DOCKER_HOST: tcp://127.0.0.1:2375 + +jobs: + build-and-push: + runs-on: container-build + steps: + - name: Build and push image + env: + REGISTRY_USER: ${{ secrets.REGISTRY_USER }} + REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} + run: | + set -eu + REF="${GITHUB_SHA:-main}" + SHORT="${REF:0:7}" + mkdir -p buildctx "${HOME}/bin" + wget -qO /tmp/repo.tar.gz \ + "https://forgejo.coulomb.social/${GITHUB_REPOSITORY}/archive/${SHORT}.tar.gz" + tar xzf /tmp/repo.tar.gz -C buildctx --strip-components=1 + wget -qO- https://download.docker.com/linux/static/stable/x86_64/docker-27.3.1.tgz \ + | tar xz --strip-components=1 -C "${HOME}/bin" docker/docker + export PATH="${HOME}/bin:${PATH}" + echo "${REGISTRY_TOKEN}" | docker login "${REGISTRY}" -u "${REGISTRY_USER}" --password-stdin + IMAGE="${REGISTRY}/${IMAGE_NAME}" + docker build -t "${IMAGE}:latest" -t "${IMAGE}:main-${SHORT}" buildctx + docker push "${IMAGE}:latest" + docker push "${IMAGE}:main-${SHORT}" + echo "pushed ${IMAGE}:latest and ${IMAGE}:main-${SHORT}" diff --git a/.forgejo/workflows/recompose-fallback.yaml b/.forgejo/workflows/recompose-fallback.yaml new file mode 100644 index 0000000..4de93da --- /dev/null +++ b/.forgejo/workflows/recompose-fallback.yaml @@ -0,0 +1,29 @@ +# Scheduled fallback recompose trigger (REUSE-WP-0019-T03 design principle 3: +# "degrade to schedule" if the org-level webhook is unavailable or misses an +# event). The webhook (POST /v1/webhooks/forgejo) is the primary path; this +# just guarantees the hub's composed index doesn't go stale indefinitely if a +# webhook delivery is ever missed. +name: Recompose Fallback + +on: + schedule: + - cron: "17 */6 * * *" + workflow_dispatch: + +jobs: + recompose: + runs-on: ubuntu-latest + steps: + - name: Trigger hub recompose + env: + REUSE_SURFACE_TOKEN: ${{ secrets.REUSE_SURFACE_TOKEN }} + run: | + set -eu + apt-get update -qq + apt-get install -y -qq curl >/dev/null + status=$(curl -sS -o /tmp/compose.json -w '%{http_code}' \ + -X POST "https://reuse.coulomb.social/v1/federated/compose" \ + -H "Authorization: Bearer ${REUSE_SURFACE_TOKEN}") + echo "status=${status}" + cat /tmp/compose.json + [ "${status}" = "200" ] diff --git a/SCOPE.md b/SCOPE.md index 8026e1a..52d2810 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -80,6 +80,11 @@ The MVP registry foundation, CLI tooling (REUSE-WP-0003), federation stack get a reuse/extend/new verdict; `--file-request` bridges a `new` verdict to a State Hub capability request; `report gaps --check-capability-requests` surfaces open requests with no matching capability +- **Get automatic hub refresh** (REUSE-WP-0019-T02) — a Forgejo push + webhook (`POST /v1/webhooks/forgejo`, HMAC-signed) recomposes the hub's + federated index when a registered repo's `registry/indexes/` changes, + with `composed_at`/`stale` visibility on `GET /v1/federated` and a + scheduled fallback recompose if a webhook delivery is ever missed Registry **tooling** availability is **A4** (CLI plus hosted hub HTTP API). Registry **authoring** remains Markdown-first; consumption combines entries, the @@ -87,9 +92,6 @@ index, CLI automation, and the production hub. ## What Is Not Possible Yet -- **Automatic hub refresh** — federated compose is on-demand; no polling or - webhooks - - **Multi-domain federation** — all indexed capabilities remain `helix_forge` - **Planning analytics breadth** — `report gaps` shipped (REUSE-WP-0015-T03); no roadmap views or standardization tracker beyond `overlaps` and compose @@ -123,8 +125,11 @@ See `tools/README.md` for command reference. - **Specs:** `specs/FederationHubAPI.md`, `schemas/hub-registration.schema.yaml`. - **Docs:** `docs/CapabilityRegistryConcept.md`, `docs/RegistryFederation.md`, `docs/IntentScopeGapAnalysis.md`, deploy guide `docs/deploy/reuse-kubernetes.md`. -- **CI:** `.gitea/workflows/ci.yml` — validate, federation compose, catalog, - graph, pytest, informational `report cohorts`, `stats --roster`, `report gaps`. +- **CI:** `.forgejo/workflows/ci.yml` — validate, federation compose, catalog, + graph, pytest, informational `report cohorts`, `stats --roster`, `report gaps` + (migrated from Gitea 2026-07-07, REUSE-WP-0019-T03). Also + `.forgejo/workflows/image.yaml` (container build/push) and + `recompose-fallback.yaml` (scheduled hub recompose, webhook backstop). - **Relation graph:** `docs/graph/capability-graph.mmd`, `docs/graph/index.html`. - **Searchable catalog:** `docs/catalog/search.html`. - **Workplans:** REUSE-WP-0001 through REUSE-WP-0015 finished (archived); diff --git a/registry/capabilities/capability.registry.register.md b/registry/capabilities/capability.registry.register.md index 3cb101b..05185f9 100644 --- a/registry/capabilities/capability.registry.register.md +++ b/registry/capabilities/capability.registry.register.md @@ -118,7 +118,7 @@ evidence: tests: - tests/test_hub.py - tests/test_hub_sync.py - - .gitea/workflows/ci.yml + - .forgejo/workflows/ci.yml consumer_feedback: - > reuse-surface dogfood (REUSE-WP-0011): production hub registration and diff --git a/registry/capabilities/capability.registry.validate.md b/registry/capabilities/capability.registry.validate.md index 9a0a401..bd68d33 100644 --- a/registry/capabilities/capability.registry.validate.md +++ b/registry/capabilities/capability.registry.validate.md @@ -77,7 +77,7 @@ relations: evidence: documentation: - tools/README.md - - .gitea/workflows/ci.yml + - .forgejo/workflows/ci.yml tests: - tests/test_registry.py consumer_feedback: