From 32ec35500ecde8236a308371d64926b46bb2bd66 Mon Sep 17 00:00:00 2001 From: Corey Leath Date: Fri, 21 Aug 2026 01:29:44 -0400 Subject: [PATCH 1/3] ci: replace auto-tagging with validated tagged releases --- .github/workflows/release.yml | 128 ++++++++++++++++++++++++++++++---- 1 file changed, 114 insertions(+), 14 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c35fb3f..5a53fae 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,26 +1,126 @@ -name: Automated Release Engineering +name: SentinelAI Release on: push: - branches: - - main + tags: + - "v*.*.*" + pull_request: + paths: + - ".github/workflows/release.yml" + - "CHANGELOG.md" + - "RELEASE_NOTES_v0.1.0.md" + +permissions: + contents: read + +concurrency: + group: sentinelai-release-${{ github.ref }} + cancel-in-progress: false jobs: - tagging-engine: - name: Construct Semantic Version Tags + validate: + name: Validate release candidate + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Verify semantic-version tag and changelog + if: startsWith(github.ref, 'refs/tags/') + shell: bash + run: | + tag="${{ github.ref_name }}" + if [[ ! "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Invalid semantic-version tag: $tag" >&2 + exit 1 + fi + version="${tag#v}" + grep -Fq "## [$version]" CHANGELOG.md + + - uses: actions/setup-python@v5 + with: + python-version: "3.11" + cache: pip + + - name: Install Python test dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements-dev.txt + + - name: Run Python test suite + env: + PYTHONPATH: . + run: pytest tests/ -q + + - uses: actions/setup-go@v5 + with: + go-version: "1.21.x" + cache-dependency-path: ingestion-service/go.sum + + - name: Run Go ingestion tests + working-directory: ingestion-service + run: go test ./... + + - name: Build ingestion container + run: docker build -t sentinelai-ingestion:release ./ingestion-service + + release: + name: Publish GitHub Release + if: startsWith(github.ref, 'refs/tags/') + needs: validate runs-on: ubuntu-latest permissions: contents: write - steps: - - name: ⬇️ Checkout Repository - uses: actions/checkout@v4 + - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: 🏷️ Calculate Release Version Alpha - uses: anothrNick/github-tag-action@1.64.0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - WITH_V: true - DEFAULT_BUMP: patch + - name: Build deterministic source archive and checksum + run: | + mkdir -p dist + git archive --format=tar --prefix="sentinelai-${{ github.ref_name }}/" "${{ github.sha }}" | gzip -n > "dist/sentinelai-${{ github.ref_name }}.tar.gz" + sha256sum "dist/sentinelai-${{ github.ref_name }}.tar.gz" > "dist/sentinelai-${{ github.ref_name }}.tar.gz.sha256" + + - name: Publish release + uses: softprops/action-gh-release@v2 + with: + body_path: RELEASE_NOTES_v0.1.0.md + generate_release_notes: false + files: | + dist/sentinelai-${{ github.ref_name }}.tar.gz + dist/sentinelai-${{ github.ref_name }}.tar.gz.sha256 + + publish-container: + name: Publish GHCR ingestion image + if: startsWith(github.ref, 'refs/tags/') + needs: release + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v4 + + - uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: docker/metadata-action@v5 + id: meta + with: + images: ghcr.io/coreyleath-code/sentinelai-ingestion + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=raw,value=latest + + - uses: docker/build-push-action@v6 + with: + context: ./ingestion-service + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} From 8dc61bb76dd717a1d2c27cdf3a2961c7d916c504 Mon Sep 17 00:00:00 2001 From: Corey Leath Date: Fri, 21 Aug 2026 01:29:55 -0400 Subject: [PATCH 2/3] docs: define SentinelAI v0.1.0 release scope --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 586574c..ddb30d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # Changelog +All notable release-level changes to SentinelAI are documented here. + +## [Unreleased] + +## [0.1.0] - 2026-08-21 + +### Added + +- Reproducible PSI/KS drift-decision benchmark artifacts and documented evidence boundaries. +- Python API test coverage and CI evidence artifacts. +- Go ingestion-service tests plus multi-replica NGINX readiness/load-balancer smoke testing. +- Security workflows covering CodeQL, SAST, dependency review, and supply-chain checks. +- A validated semantic-tag release workflow that creates a GitHub Release and publishes the Go ingestion service to GHCR. + +### Changed + +- Release automation now requires an explicit semantic-version tag instead of creating tags on every push to `main`. +- Release claims are scoped to implemented statistical drift monitoring, reproducible synthetic benchmarks, and repository-verified service behavior; no production model-quality or fleet-scale performance claim is introduced. + ## 2026-08-05 ### Recent Code Improvements From fa36cb86a209f85c52b5d8a83bb7b7ff1226bb09 Mon Sep 17 00:00:00 2001 From: Corey Leath Date: Fri, 21 Aug 2026 01:30:03 -0400 Subject: [PATCH 3/3] docs: add SentinelAI v0.1.0 release notes --- RELEASE_NOTES_v0.1.0.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 RELEASE_NOTES_v0.1.0.md diff --git a/RELEASE_NOTES_v0.1.0.md b/RELEASE_NOTES_v0.1.0.md new file mode 100644 index 0000000..ad575e8 --- /dev/null +++ b/RELEASE_NOTES_v0.1.0.md @@ -0,0 +1,36 @@ +# SentinelAI v0.1.0 + +SentinelAI v0.1.0 is the first formal portfolio release of the repository's reproducible drift-monitoring reference system. + +## Release scope + +The directly implemented statistical path compares expected and observed histograms with Population Stability Index (PSI) and a Kolmogorov-Smirnov CDF distance, then flags drift when the configured thresholds are crossed. The repository's benchmark evidence is synthetic and reproducible; it is not presented as production drift-detection accuracy, native C++ service latency, or fleet-scale throughput. + +## Verified repository surface + +The release candidate is gated by: + +- the Python test suite; +- Go tests for the ingestion service; +- a container build for the ingestion service; +- the repository's existing CI, benchmark, schema-validation, and security workflows. + +The existing CI also exercises the ingestion path behind NGINX with three replicas and verifies readiness survives loss of one backend. + +## Release artifacts + +A successful `v0.1.0` tag publishes: + +- a deterministic source archive and SHA-256 checksum on the GitHub Release; +- the validated Go ingestion-service container at `ghcr.io/coreyleath-code/sentinelai-ingestion:0.1.0`; +- additional GHCR tags for `0.1` and `latest`. + +## Reproducibility + +The statistical benchmark can be regenerated with: + +```bash +python benchmarks/run_benchmark.py --output benchmarks/latest.json +``` + +The release does not add or imply production authorization, calibrated statistical significance, production model-quality guarantees, or cross-hardware performance guarantees.