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
44 changes: 44 additions & 0 deletions .github/workflows/rc-adopter-gate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: RC Adopter Gate

on:
workflow_dispatch:
inputs:
version:
description: Published Codes RC version
required: true
default: 0.4.0-RC1

permissions:
contents: read

jobs:
adopters:
runs-on: ubuntu-latest
timeout-minutes: 45

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
ref: v${{ inputs.version }}
persist-credentials: false

- uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95
with:
distribution: temurin
java-version: "21"

- name: Verify external adopter gate
run: >-
bash scripts/verify-rc-adopters.sh
"${{ inputs.version }}"
build/reports/rc1-adopters.md

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
if: always()
with:
name: rc1-adopter-gate-manual
path: |
build/reports/rc1-adopters.md
build/rc-adopters/*.log
if-no-files-found: warn
retention-days: 30
180 changes: 180 additions & 0 deletions .github/workflows/release-candidate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
name: Release Candidate

on:
push:
tags:
- "v*.*.*-RC*"

permissions:
contents: read

concurrency:
group: maven-central-release
cancel-in-progress: false

jobs:
publish:
runs-on: ubuntu-latest
timeout-minutes: 90
outputs:
version: ${{ steps.version.outputs.value }}

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: 0
persist-credentials: false

- id: version
name: Verify release-candidate tag
shell: bash
run: |
set -euo pipefail

version="$(sh ./scripts/version.sh)"

[[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+-RC[1-9][0-9]*$ ]] || {
echo "Invalid release-candidate version: $version"
exit 1
}

test "${GITHUB_REF_NAME}" = "v${version}"

git fetch --no-tags origin main

test "$(git rev-parse "${GITHUB_SHA}^{commit}")" = \
"$(git rev-parse "origin/main^{commit}")"

echo "value=$version" >> "$GITHUB_OUTPUT"

- uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95
with:
distribution: temurin
java-version: "17"

- uses: gradle/actions/setup-gradle@3f131e8634966bd73d06cc69884922b02e6faf92
with:
cache-provider: basic

- name: Verify release-candidate tree
run: |
python scripts/verify-compatibility-matrix.py
./gradlew clean verifyAll --stacktrace

- name: Publish clean release-candidate artifacts
run: bash scripts/prepare-compatibility-repository.sh build/compatibility-maven

- name: Verify published-artifact consumers before Central
shell: bash
env:
MAVEN_REPO_LOCAL: ${{ github.workspace }}/build/compatibility-maven
run: |
set -euo pipefail
version="$(sh ./scripts/version.sh)"

./gradlew \
-p smoke-test-java \
"-Dmaven.repo.local=${MAVEN_REPO_LOCAL}" \
clean check \
--stacktrace

./gradlew \
-p smoke-test-kotlin \
"-Dmaven.repo.local=${MAVEN_REPO_LOCAL}" \
clean check \
--stacktrace

mvn --batch-mode --no-transfer-progress \
"-Dmaven.repo.local=${MAVEN_REPO_LOCAL}" \
-f smoke-test-maven-java/pom.xml \
"-Dcodes.version=$version" \
clean verify

bash ./scripts/verify-kotlin-nullability.sh 2.4.10

- name: Publish all Codes artifacts to Maven Central
run: >-
./gradlew
:publishToMavenCentral
:codes-spring:publishToMavenCentral
:codes-grpc-java:publishToMavenCentral
--no-configuration-cache
--stacktrace
env:
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_IN_MEMORY_KEY }}
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_IN_MEMORY_KEY_PASSWORD }}

real-adopters:
needs: publish
runs-on: ubuntu-latest
timeout-minutes: 45

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: false

- uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95
with:
distribution: temurin
java-version: "21"

- name: Verify two external adopters from Maven Central
run: >-
bash scripts/verify-rc-adopters.sh
"${{ needs.publish.outputs.version }}"
build/reports/rc1-adopters.md

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
if: always()
with:
name: rc1-adopter-gate
path: |
build/reports/rc1-adopters.md
build/rc-adopters/*.log
if-no-files-found: warn
retention-days: 30

github-prerelease:
needs: [publish, real-adopters]
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: false

- name: Create GitHub prerelease
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail

version="${GITHUB_REF_NAME#v}"

awk -v version="$version" '
$0 == "## " version {
capture = 1
next
}
capture && /^## / {
exit
}
capture {
print
}
' CHANGELOG.md > release-notes.md

test -s release-notes.md

gh release create "$GITHUB_REF_NAME" \
--verify-tag \
--prerelease \
--title "Codes $version" \
--notes-file release-notes.md
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
tags:
- "v*.*.*"
- "!v*.*.*-RC*"

permissions:
contents: read
Expand Down
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

## Unreleased

## 0.4.0-RC1

### Added

* Added Maven publications for `codes-spring` and `codes-grpc-java`.
* Added adapter API snapshots and exact published dependency budgets.
* Added clean Gradle and Maven consumer checks that resolve all three artifacts from Maven Local.
* Added clean Gradle and Maven consumer checks that resolve all three artifacts from isolated publication repositories.
* Added application-owned Spring problem-type URI mappings.
* Added a thin failed-`Outcome` to Spring `ErrorResponseException` bridge.
* Added Spring RFC 9457 golden response contracts plus MVC and WebFlux compatibility checks.
Expand All @@ -15,17 +17,21 @@
* Added a production compatibility matrix for Spring 6/7, minimum/current gRPC, Java 17/21/25, Java/Kotlin consumers, Gradle/Maven, and Linux/Windows/macOS.
* Added adapter JSpecify consumer verification and adapter coverage gates.
* Added published-POM verification against clean isolated Maven repositories.
* Added ten-minute Spring and gRPC boundary examples.
* Added a reproducible release-candidate adopter gate against two pinned external codebases.
* Added a dedicated release-candidate workflow that publishes to Maven Central before running the external adopter gate.

### Changed

* Aligned all publishable modules on the shared `0.4.0-SNAPSHOT` version.
* Set all publishable modules to `0.4.0-RC1`.
* Corrected Spring problem details so reusable outcome messages are titles for explicitly mapped problem types and occurrence details use RFC `detail`.
* Kept stable Codes identity in the Spring `code` extension for every mapped failure.
* Reworked the Spring orders reference to consume `codes-spring` instead of duplicating adapter behavior.
* Enforced lossless Codes identity compatibility with `google.rpc.ErrorInfo.domain` and `ErrorInfo.reason`.
* Preserved exposed structured issues through `google.rpc.BadRequest` without normalizing coded issue identity.
* Reworked the gRPC orders reference to consume `codes-grpc-java` instead of constructing rich error details manually.
* Moved publication consumer verification to freshly emptied Maven repositories so compatibility checks cannot be satisfied by stale local artifacts.
* Documented cases where Codes should not be introduced.

## 0.3.1

Expand Down
48 changes: 48 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Code of Conduct

Keep project interaction technical, professional, and useful.

## Expected behavior

- Criticize code, design, tests, or reasoning. Do not attack the person.
- Keep issues, reviews, and discussions on topic.
- Back technical claims with evidence when possible.
- Accept review feedback and rejected proposals without making it personal.
- Respect privacy.

Strong disagreement is fine.

Harassment is not.

## Unacceptable behavior

The following is not accepted:

- harassment or discrimination
- threats or intimidation
- personal attacks
- trolling or deliberate provocation
- publishing private information
- sustained bad-faith disruption
- spam, including automated or AI-generated issue and pull-request spam
- abusive language directed at contributors or maintainers

Technical criticism is not a Code of Conduct violation merely because it is direct.

Keep it about the work.

## Enforcement

The maintainer may remove content, close issues or pull requests, restrict participation, or temporarily or permanently block contributors.

Serious abuse does not require a warning before action is taken.

## Reporting conduct problems

If a report contains harassment, threats, private information, or anything else that should not be public, contact the maintainer privately using the contact information on the maintainer's GitHub profile.

Do not create a public issue containing sensitive personal information.

## One rule

Be useful. Be respectful. Keep it about the work.
Loading
Loading