Skip to content

Commit 810fc14

Browse files
committed
wip: release automation: tag workflow, secrets helper, docs
1 parent c150fdd commit 810fc14

File tree

13 files changed

+648
-6
lines changed

13 files changed

+648
-6
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
name: Release on Tag
2+
3+
on:
4+
push:
5+
tags:
6+
- 'releases/*'
7+
8+
permissions:
9+
contents: write # push tags, push commits
10+
pull-requests: write
11+
12+
concurrency:
13+
group: release-${{ github.ref }}
14+
cancel-in-progress: false
15+
16+
jobs:
17+
release:
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: Checkout
21+
uses: actions/checkout@v4
22+
with:
23+
fetch-depth: 0
24+
25+
- name: Set up Java, Central creds and GPG
26+
uses: actions/setup-java@v4
27+
with:
28+
distribution: temurin
29+
java-version: '21'
30+
cache: maven
31+
server-id: central
32+
server-username: CENTRAL_USERNAME
33+
server-password: CENTRAL_PASSWORD
34+
gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
35+
gpg-passphrase: ${{ secrets.GPG_PASSPHRASE }}
36+
37+
- name: Create GitHub Release with notes
38+
uses: softprops/action-gh-release@v2
39+
with:
40+
tag_name: ${{ github.ref_name }}
41+
generate_release_notes: true
42+
43+
- name: Build and Deploy to Central
44+
env:
45+
CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }}
46+
CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }}
47+
run: |
48+
mvn -B -ntp clean deploy
49+
50+
- name: Configure Git identity
51+
run: |
52+
git config user.name "github-actions[bot]"
53+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
54+
55+
- name: Create branch from tag for PR
56+
id: prbranch
57+
run: |
58+
BRANCH_NAME="release-bot-$(date +%Y%m%d-%H%M%S)"
59+
git checkout -B "$BRANCH_NAME" $GITHUB_SHA
60+
git push origin "$BRANCH_NAME"
61+
echo "branch=$BRANCH_NAME" >> "$GITHUB_OUTPUT"
62+
63+
- name: Open PR back to main
64+
env:
65+
GH_TOKEN: ${{ github.token }}
66+
run: |
67+
gh pr create \
68+
--title "chore: merge release ${{ github.ref_name }} to main" \
69+
--body "Automated PR created from tag ${{ github.ref_name }}." \
70+
--base main \
71+
--head "${{ steps.prbranch.outputs.branch }}" \
72+
|| echo "PR already exists or nothing to compare"

AGENTS.md

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,47 @@ mvn exec:java -pl json-compatibility-suite -Dexec.args="--json"
6464
./mvn-test-no-boilerplate.sh -Dtest=JsonParserTests -Djava.util.logging.ConsoleHandler.level=FINER
6565
```
6666

67+
## Releasing to Maven Central
68+
69+
Prerequisites
70+
- Central credentials in `~/.m2/settings.xml` with `<id>central</id>` (used by the workflow)
71+
```xml
72+
<servers>
73+
<server>
74+
<id>central</id>
75+
<username>YOUR_PORTAL_TOKEN_USERNAME</username>
76+
<password>YOUR_PORTAL_TOKEN_PASSWORD</password>
77+
</server>
78+
</servers>
79+
```
80+
- GPG key set up for signing (the parent POM runs `maven-gpg-plugin` in `verify`). If prompted for passphrase locally, export `GPG_TTY=$(tty)` or configure passphrase in settings. In CI, secrets `GPG_PRIVATE_KEY` and `GPG_PASSPHRASE` are used.
81+
- Optional: alias `mvn` to `mvnd` for faster builds (see note at top).
82+
83+
Automated Release (preferred)
84+
- Push a tag named `releases/X.Y.Z` (semver, no leading `v`).
85+
- The workflow `.github/workflows/release-on-branch.yml` will:
86+
- Create a GitHub Release for that tag with autogenerated notes.
87+
- Build and deploy artifacts to Maven Central (Central Publishing plugin).
88+
- Create a branch `release-bot-YYYYMMDD-HHMMSS` at the tagged commit and open a PR back to `main` (no version bumps).
89+
90+
Manual Release (local)
91+
- Ensure POM version is your intended release version.
92+
- Verify: `mvn verify`
93+
- Publish: `mvn clean deploy` (uses Central Publishing plugin + GPG)
94+
- Tag with `releases/X.Y.Z` and create a GitHub Release if desired.
95+
96+
Snapshot Publishing
97+
- Set version to `X.Y.(Z+1)-SNAPSHOT`:
98+
- `mvn -q versions:set -DnewVersion=0.1.1-SNAPSHOT`
99+
- Deploy snapshots:
100+
- `mvn clean deploy`
101+
- Goes to `https://oss.sonatype.org/content/repositories/snapshots` (configured in `distributionManagement`).
102+
103+
Notes
104+
- Javadoc is built with `doclint` disabled to avoid strict failures on Java 21.
105+
- To skip signing locally for quick checks, add `-Dgpg.skip=true`.
106+
- The Central Publishing plugin configuration lives in the parent `pom.xml` and applies to all modules.
107+
67108
## Python Usage (Herodoc, 3.2-safe)
68109
- Prefer `python3` with a heredoc over Perl/sed for non-trivial transforms.
69110
- Target ancient Python 3.2 syntax: no f-strings, no fancy deps.
@@ -186,7 +227,7 @@ PY
186227

187228
### json-java21
188229
- **Main library** containing the core JSON API
189-
- **Maven coordinates**: `io.github.simbo1905.json:json-java21:0.1-SNAPSHOT`
230+
- **Maven coordinates**: `io.github.simbo1905.json:json-java21:0.X.Y`
190231
- **JDK requirement**: Java 21+
191232

192233
### json-compatibility-suite

RELEASE-GIST.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Tag-Triggered Maven Central Release (GitHub Actions)
2+
3+
- Trigger: push tag `releases/X.Y.Z` (no leading `v`).
4+
- CI creates a GitHub Release from the tag, then deploys to Maven Central.
5+
- CI opens a PR back to `main` from `release-bot-YYYYMMDD-HHMMSS` (no version bumps).
6+
7+
## Workflow (drop-in)
8+
9+
```yaml
10+
name: Release on Tag
11+
on:
12+
push:
13+
tags:
14+
- 'releases/*'
15+
permissions:
16+
contents: write
17+
pull-requests: write
18+
jobs:
19+
release:
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: actions/checkout@v4
23+
with: { fetch-depth: 0 }
24+
- uses: actions/setup-java@v4
25+
with:
26+
distribution: temurin
27+
java-version: '21'
28+
cache: maven
29+
server-id: central
30+
server-username: CENTRAL_USERNAME
31+
server-password: CENTRAL_PASSWORD
32+
gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
33+
gpg-passphrase: ${{ secrets.GPG_PASSPHRASE }}
34+
- uses: softprops/action-gh-release@v2
35+
with:
36+
tag_name: ${{ github.ref_name }}
37+
generate_release_notes: true
38+
- name: Build and Deploy to Central
39+
env:
40+
CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }}
41+
CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }}
42+
run: mvn -B -ntp clean deploy
43+
- name: Configure Git identity
44+
run: |
45+
git config user.name "github-actions[bot]"
46+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
47+
- name: Create branch from tag and PR to main
48+
env: { GH_TOKEN: ${{ github.token }} }
49+
run: |
50+
BRANCH_NAME="release-bot-$(date +%Y%m%d-%H%M%S)"
51+
git checkout -B "$BRANCH_NAME" $GITHUB_SHA
52+
git push origin "$BRANCH_NAME"
53+
gh pr create \
54+
--title "chore: merge release ${{ github.ref_name }} to main" \
55+
--body "Automated PR created from tag ${{ github.ref_name }}." \
56+
--base main \
57+
--head "$BRANCH_NAME" || true
58+
```
59+
60+
## Secrets (one-time)
61+
62+
- CENTRAL_USERNAME, CENTRAL_PASSWORD (Central Portal token)
63+
- GPG_PRIVATE_KEY (ASCII-armored secret key), GPG_PASSPHRASE
64+
65+
zsh helper (uses gh, gpg):
66+
67+
```zsh
68+
#!/usr/bin/env zsh
69+
set -euo pipefail
70+
export CENTRAL_USERNAME=your_user
71+
export CENTRAL_PASSWORD=your_pass
72+
export GPG_PASSPHRASE=your_passphrase
73+
export GPG_KEY_ID=YOUR_KEY_ID # or export GPG_PRIVATE_KEY="$(gpg --armor --export-secret-keys YOUR_KEY_ID)"
74+
./scripts/setup-release-secrets.zsh
75+
```
76+
77+
## Trigger a Release
78+
79+
```bash
80+
git tag 'releases/0.1.0'
81+
git push origin 'releases/0.1.0'
82+
```
83+
84+
## Publish this doc as a Gist
85+
86+
```bash
87+
gh gist create -p -d "Tag-triggered Maven Central release via GitHub Actions" RELEASE-GIST.md
88+
```

json-compatibility-suite/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>io.github.simbo1905.json</groupId>
99
<artifactId>json-java21-parent</artifactId>
10-
<version>0.1-SNAPSHOT</version>
10+
<version>0.1.0</version>
1111
</parent>
1212

1313
<artifactId>json-compatibility-suite</artifactId>

json-java21-api-tracker/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>io.github.simbo1905.json</groupId>
99
<artifactId>json-java21-parent</artifactId>
10-
<version>0.1-SNAPSHOT</version>
10+
<version>0.1.0</version>
1111
</parent>
1212

1313
<artifactId>json-java21-api-tracker</artifactId>

json-java21-schema/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<parent>
99
<groupId>io.github.simbo1905.json</groupId>
1010
<artifactId>json-java21-parent</artifactId>
11-
<version>0.1-SNAPSHOT</version>
11+
<version>0.1.0</version>
1212
</parent>
1313

1414
<artifactId>json-java21-schema</artifactId>

json-java21/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>io.github.simbo1905.json</groupId>
99
<artifactId>json-java21-parent</artifactId>
10-
<version>0.1-SNAPSHOT</version>
10+
<version>0.1.0</version>
1111
</parent>
1212

1313
<artifactId>json-java21</artifactId>

pom.xml

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>io.github.simbo1905.json</groupId>
88
<artifactId>json-java21-parent</artifactId>
9-
<version>0.1-SNAPSHOT</version>
9+
<version>0.1.0</version>
1010
<packaging>pom</packaging>
1111

1212
<name>java.util.json Backport Parent</name>
@@ -56,6 +56,8 @@
5656
<maven-jar-plugin.version>3.4.2</maven-jar-plugin.version>
5757
<maven-install-plugin.version>3.1.2</maven-install-plugin.version>
5858
<download-maven-plugin.version>1.7.1</download-maven-plugin.version>
59+
<!-- Ensure GPG is enabled by default for releases -->
60+
<gpg.skip>false</gpg.skip>
5961
</properties>
6062

6163

@@ -123,5 +125,79 @@
123125
</plugin>
124126
</plugins>
125127
</pluginManagement>
128+
<!-- Inherited by all modules: attach sources/javadoc, sign, and publish via Central Portal -->
129+
<plugins>
130+
<plugin>
131+
<groupId>org.apache.maven.plugins</groupId>
132+
<artifactId>maven-source-plugin</artifactId>
133+
<version>3.3.0</version>
134+
<executions>
135+
<execution>
136+
<id>attach-sources</id>
137+
<goals>
138+
<goal>jar-no-fork</goal>
139+
</goals>
140+
</execution>
141+
</executions>
142+
</plugin>
143+
<plugin>
144+
<groupId>org.apache.maven.plugins</groupId>
145+
<artifactId>maven-javadoc-plugin</artifactId>
146+
<version>3.5.0</version>
147+
<configuration>
148+
<release>21</release>
149+
<doclint>none</doclint>
150+
</configuration>
151+
<executions>
152+
<execution>
153+
<id>attach-javadocs</id>
154+
<goals>
155+
<goal>jar</goal>
156+
</goals>
157+
</execution>
158+
</executions>
159+
</plugin>
160+
<plugin>
161+
<groupId>org.apache.maven.plugins</groupId>
162+
<artifactId>maven-gpg-plugin</artifactId>
163+
<version>3.1.0</version>
164+
<executions>
165+
<execution>
166+
<id>sign-artifacts</id>
167+
<phase>verify</phase>
168+
<goals>
169+
<goal>sign</goal>
170+
</goals>
171+
</execution>
172+
</executions>
173+
<configuration>
174+
<skip>${gpg.skip}</skip>
175+
<gpgArguments>
176+
<arg>--pinentry-mode</arg>
177+
<arg>loopback</arg>
178+
</gpgArguments>
179+
</configuration>
180+
</plugin>
181+
<plugin>
182+
<groupId>org.sonatype.central</groupId>
183+
<artifactId>central-publishing-maven-plugin</artifactId>
184+
<version>0.6.0</version>
185+
<extensions>true</extensions>
186+
<configuration>
187+
<publishingServerId>central</publishingServerId>
188+
<autoPublish>true</autoPublish>
189+
<waitUntil>published</waitUntil>
190+
</configuration>
191+
</plugin>
192+
</plugins>
126193
</build>
194+
195+
<!-- Snapshots go to OSSRH; releases go via Central Publishing Portal -->
196+
<distributionManagement>
197+
<snapshotRepository>
198+
<id>ossrh</id>
199+
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
200+
</snapshotRepository>
201+
</distributionManagement>
202+
127203
</project>

0 commit comments

Comments
 (0)