From 476ef70c4d5ba800f9e29bb5002f12891eb3e4cc Mon Sep 17 00:00:00 2001 From: Yordis Prieto Date: Tue, 1 Sep 2026 15:12:09 -0400 Subject: [PATCH] chore(release): enforce release readiness Signed-off-by: Yordis Prieto --- .config/mise/tasks/release-metadata/check | 52 +++++++++++++++++++ .github/CODEOWNERS | 24 +-------- .../workflows/build-container-ubuntu-lts.yml | 23 +++++--- .github/workflows/build-ubuntu-lts-arm64.yml | 21 +++++--- .github/workflows/build-ubuntu-lts-x64.yml | 21 +++++--- .github/workflows/common.yml | 45 +++++++++++++--- .github/workflows/release-please.yml | 25 +++++++++ .release-please-manifest.json | 3 ++ release-please-config.json | 26 ++++++++++ src/Directory.Build.props | 19 ++++--- src/EventStore.Common/Utils/VersionInfo.cs | 2 +- .../Utils/version.properties | 2 +- ...rogonEventStore.SemanticConventions.csproj | 1 - version.txt | 1 + 14 files changed, 200 insertions(+), 65 deletions(-) create mode 100755 .config/mise/tasks/release-metadata/check create mode 100644 .github/workflows/release-please.yml create mode 100644 .release-please-manifest.json create mode 100644 release-please-config.json create mode 100644 version.txt diff --git a/.config/mise/tasks/release-metadata/check b/.config/mise/tasks/release-metadata/check new file mode 100755 index 0000000000..cc75f7bb3b --- /dev/null +++ b/.config/mise/tasks/release-metadata/check @@ -0,0 +1,52 @@ +#!/bin/sh +#MISE description="Verify synchronized server release metadata" + +set -eu + +root=$(CDPATH='' cd -- "$(dirname -- "$0")/../../../.." && pwd) +manifest="$root/.release-please-manifest.json" +config="$root/release-please-config.json" +props="$root/src/Directory.Build.props" +runtime_properties="$root/src/EventStore.Common/Utils/version.properties" + +manifest_version=$(jq -er '."."' "$manifest") +file_version=$(tr -d '\r\n' <"$root/version.txt") +props_version=$(sed -n 's:.*\([^<]*\).*:\1:p' "$props") +props_suffix=$(sed -n 's:.*\([^<]*\).*:\1:p' "$props") +runtime_suffix=$(sed -n 's/^version_suffix=//p' "$runtime_properties") +bootstrap_sha=$(jq -er '."bootstrap-sha"' "$config") + +if ! printf '%s\n' "$manifest_version" | grep -Eq '^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$'; then + echo "The release manifest must contain a stable semantic version." >&2 + exit 1 +fi + +if [ "$manifest_version" != "$file_version" ] || [ "$manifest_version" != "$props_version" ]; then + echo "Release versions must match across the manifest, version.txt, and Directory.Build.props." >&2 + exit 1 +fi + +if ! grep -Eq '|>)' "$props" || + ! grep -q '^version_suffix=$' "$runtime_properties" || + [ -n "$props_suffix" ] || [ -n "$runtime_suffix" ]; then + echo "Stable release metadata cannot carry a prerelease suffix." >&2 + exit 1 +fi + +if ! printf '%s\n' "$bootstrap_sha" | grep -Eq '^[0-9a-f]{40}$'; then + echo "The release bootstrap must be a full lowercase commit SHA." >&2 + exit 1 +fi + +git -C "$root" cat-file -e "$bootstrap_sha^{commit}" + +jq -e ' + .packages["."]."release-type" == "simple" and + .packages["."]."include-component-in-tag" == false and + .packages["."]."include-v-in-tag" == true and + .packages["."]."include-v-in-release-name" == false and + any(.packages["."]."extra-files"[]; + .type == "xml" and + .path == "src/Directory.Build.props" and + .xpath == "//VersionPrefix") +' "$config" >/dev/null diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 58744bac6b..51ebfae746 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,22 +1,2 @@ -# Each line is a file pattern followed by one or more owners. - -# database-mergers team is the default owner for everything in -# the repo. Unless a later match takes precedence. -* @EventStore/database-mergers - -# documentation and database-mergers teams own any files in the 'docs' -# directory at the root of the repository and any of its -# subdirectories. -/docs/ @EventStore/documentation @EventStore/database-mergers - -# documentation and database-mergers teams own any markdown files -# in the root of the repository (README, CONTRIBUTING, LICENSING, etc.) -# Either team will be able to approve PRs changing these files. -/*.md @EventStore/documentation @EventStore/database-mergers - -# eventstore-admin team owns the codeowners file to prevent -# unauthorized changes to it. -/.github/CODEOWNERS @EventStore/eventstore-admin - -# protected because it contains license rules -/qodana.yaml @EventStore/eventstore-admin +# Review ownership belongs to human maintainers rather than individual or automation accounts. +* @TrogonStack/trogon-eventstore-maintainers diff --git a/.github/workflows/build-container-ubuntu-lts.yml b/.github/workflows/build-container-ubuntu-lts.yml index 4c847f6f41..3e7e80eff4 100644 --- a/.github/workflows/build-container-ubuntu-lts.yml +++ b/.github/workflows/build-container-ubuntu-lts.yml @@ -2,10 +2,6 @@ name: Ubuntu LTS Container on: pull_request: - paths-ignore: - - "docs/**" - - "samples/**" - - "**.md" merge_group: types: - checks_requested @@ -15,10 +11,6 @@ on: - release/v* tags: - v* - paths-ignore: - - "docs/**" - - "samples/**" - - "**.md" concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -142,3 +134,18 @@ jobs: with: image-artifact-name: eventstore-image-noble-linux-x64 secrets: inherit + + required: + name: Container CI + if: ${{ always() }} + needs: + - build-images + - test + - client-compatibility + runs-on: ubuntu-latest + permissions: {} + steps: + - name: Require successful jobs + env: + REQUIRED_JOBS: ${{ toJSON(needs) }} + run: jq -e 'all(.[]; .result == "success")' <<< "$REQUIRED_JOBS" diff --git a/.github/workflows/build-ubuntu-lts-arm64.yml b/.github/workflows/build-ubuntu-lts-arm64.yml index 727cb503bb..2c7e9e2814 100644 --- a/.github/workflows/build-ubuntu-lts-arm64.yml +++ b/.github/workflows/build-ubuntu-lts-arm64.yml @@ -2,10 +2,6 @@ name: Ubuntu LTS ARM64 on: pull_request: - paths-ignore: - - "docs/**" - - "samples/**" - - "**.md" merge_group: types: - checks_requested @@ -15,10 +11,6 @@ on: - release/v* tags: - v* - paths-ignore: - - "docs/**" - - "samples/**" - - "**.md" concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -32,3 +24,16 @@ jobs: os: ubuntu-24.04-arm arch: arm64 secrets: inherit + + required: + name: ARM64 CI + if: ${{ always() }} + needs: + - build + runs-on: ubuntu-latest + permissions: {} + steps: + - name: Require successful jobs + env: + REQUIRED_JOBS: ${{ toJSON(needs) }} + run: jq -e 'all(.[]; .result == "success")' <<< "$REQUIRED_JOBS" diff --git a/.github/workflows/build-ubuntu-lts-x64.yml b/.github/workflows/build-ubuntu-lts-x64.yml index 1cd88f24cc..0e08a8f233 100644 --- a/.github/workflows/build-ubuntu-lts-x64.yml +++ b/.github/workflows/build-ubuntu-lts-x64.yml @@ -2,10 +2,6 @@ name: Ubuntu LTS X64 on: pull_request: - paths-ignore: - - "docs/**" - - "samples/**" - - "**.md" merge_group: types: - checks_requested @@ -15,10 +11,6 @@ on: - release/v* tags: - v* - paths-ignore: - - "docs/**" - - "samples/**" - - "**.md" jobs: build: @@ -28,3 +20,16 @@ jobs: os: ubuntu-24.04 arch: x64 secrets: inherit + + required: + name: X64 CI + if: ${{ always() }} + needs: + - build + runs-on: ubuntu-latest + permissions: {} + steps: + - name: Require successful jobs + env: + REQUIRED_JOBS: ${{ toJSON(needs) }} + run: jq -e 'all(.[]; .result == "success")' <<< "$REQUIRED_JOBS" diff --git a/.github/workflows/common.yml b/.github/workflows/common.yml index c96d76a860..78d4a78656 100644 --- a/.github/workflows/common.yml +++ b/.github/workflows/common.yml @@ -2,10 +2,6 @@ name: Common on: pull_request: - paths-ignore: - - "docs/**" - - "samples/**" - - "**.md" merge_group: types: - checks_requested @@ -16,10 +12,6 @@ on: - release/v* tags: - v* - paths-ignore: - - "docs/**" - - "samples/**" - - "**.md" concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -130,6 +122,24 @@ jobs: run: | ./protolock.sh status --uptodate + release-metadata: + runs-on: ubuntu-latest + name: Release Metadata + steps: + - name: Checkout + uses: actions/checkout@v7 + with: + fetch-depth: 0 + persist-credentials: false + - name: Install task runner + uses: jdx/mise-action@v4.3.0 + with: + version: 2026.8.2 + install: false + cache: false + - name: Verify release metadata + run: mise run --skip-tools release-metadata:check + archive-storage-contract: runs-on: ubuntu-latest name: Archive Storage Contract @@ -224,3 +234,22 @@ jobs: DOCKER_BUILDKIT: 1 NUGET_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: mise run --skip-tools github-actions:docker-compose-smoke + + required: + name: Common CI + if: ${{ always() }} + needs: + - semantic-conventions + - csharp-quality + - vulnerability-scan + - protolock + - release-metadata + - archive-storage-contract + - docker-compose + runs-on: ubuntu-latest + permissions: {} + steps: + - name: Require successful jobs + env: + REQUIRED_JOBS: ${{ toJSON(needs) }} + run: jq -e 'all(.[]; .result == "success")' <<< "$REQUIRED_JOBS" diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml new file mode 100644 index 0000000000..29eccf78e5 --- /dev/null +++ b/.github/workflows/release-please.yml @@ -0,0 +1,25 @@ +name: Release Please + +on: + push: + branches: + - master + workflow_dispatch: + +permissions: + contents: write + issues: write + pull-requests: write + +jobs: + release-please: + name: Release Please + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Create release pull request or release + uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0 + with: + token: ${{ secrets.GH_PAT_RELEASE_PLEASE_ACTION }} + config-file: release-please-config.json + manifest-file: .release-please-manifest.json diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000000..b985ff6e79 --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.0.1" +} diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 0000000000..aede355db0 --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "bootstrap-sha": "10b210b00594fb80a99730991a91b29699094e44", + "group-pull-request-title-pattern": "chore${scope}: release${component} ${version}", + "signoff": "SHT Bot <61149376+sht-bot@users.noreply.github.com>", + "packages": { + ".": { + "release-type": "simple", + "package-name": "TrogonEventStore", + "component": "TrogonEventStore", + "include-component-in-tag": false, + "include-v-in-tag": true, + "include-v-in-release-name": false, + "pull-request-title-pattern": "chore${scope}: release${component} ${version}", + "bump-minor-pre-major": false, + "bump-patch-for-minor-pre-major": false, + "extra-files": [ + { + "type": "xml", + "path": "src/Directory.Build.props", + "xpath": "//VersionPrefix" + } + ] + } + } +} diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 459cdc5194..c93bfc8b77 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -3,23 +3,26 @@ Debug full pdbonly - Event Store Ltd - ouro.png + Straw Hat, LLC + Straw Hat, LLC + trogon-logo.png LICENSE.md - https://eventstore.com + https://github.com/TrogonStack/TrogonEventStore false - Copyright 2012-2024 Event Store Ltd - https://eventstore.com/blog/ + Copyright 2011-2024, Event Store Ltd; Copyright 2025-2026, Straw Hat, LLC + https://github.com/TrogonStack/TrogonEventStore/releases + git + https://github.com/TrogonStack/TrogonEventStore net10.0 14.0 AnyCPU;x64;ARM64 false - 24.10.0 - prerelease + 0.0.1 + - + diff --git a/src/EventStore.Common/Utils/VersionInfo.cs b/src/EventStore.Common/Utils/VersionInfo.cs index 37ea094bf0..f13c06e4c2 100644 --- a/src/EventStore.Common/Utils/VersionInfo.cs +++ b/src/EventStore.Common/Utils/VersionInfo.cs @@ -22,7 +22,7 @@ public static class VersionInfo public static string CommitSha { get; private set; } = ThisAssembly.Git.Commit; public static string Timestamp { get; private set; } = ThisAssembly.Git.CommitDate; - public static string Text => $"EventStoreDB version {Version} {Edition} ({BuildId}/{CommitSha})"; + public static string Text => $"TrogonEventStore version {Version} {Edition} ({BuildId}/{CommitSha})"; static VersionInfo() { diff --git a/src/EventStore.Common/Utils/version.properties b/src/EventStore.Common/Utils/version.properties index 35aa94652e..057c529c30 100644 --- a/src/EventStore.Common/Utils/version.properties +++ b/src/EventStore.Common/Utils/version.properties @@ -1,2 +1,2 @@ -version_suffix=prerelease +version_suffix= edition=local diff --git a/src/TrogonEventStore.SemanticConventions/TrogonEventStore.SemanticConventions.csproj b/src/TrogonEventStore.SemanticConventions/TrogonEventStore.SemanticConventions.csproj index 112f01af2e..c2c34085d5 100644 --- a/src/TrogonEventStore.SemanticConventions/TrogonEventStore.SemanticConventions.csproj +++ b/src/TrogonEventStore.SemanticConventions/TrogonEventStore.SemanticConventions.csproj @@ -20,6 +20,5 @@ - diff --git a/version.txt b/version.txt new file mode 100644 index 0000000000..8acdd82b76 --- /dev/null +++ b/version.txt @@ -0,0 +1 @@ +0.0.1