Skip to content

Commit d21ff7d

Browse files
7agustibmclaude
andcommitted
ci: derive the published version from the tag and add a changelog
The version was a literal in build.gradle.kts while the deploy workflow triggered on v* tags and picked its target repository from the -SNAPSHOT suffix. Pushing v7.0.0 without editing the build first therefore published 7.0.0-SNAPSHOT to the snapshots repository and reported success — the one class of mistake that cannot be undone afterwards, since a published coordinate is immutable. The version now comes from the tag, guarded by GITHUB_REF_TYPE so a branch build does not publish a version named after the branch, and the workflow checks both that the tag looks like a version and that the build agrees with it before anything is published. Verified: no env -> 7.0.0-SNAPSHOT, tag v7.0.0 -> 7.0.0, branch main -> 7.0.0-SNAPSHOT, tag v7.1.0-rc.1 -> 7.1.0-rc.1. The changelog starts at 7.0.0; its content is the README's migration guide plus the fixes made while preparing this release. The date is left open until the tag is actually cut. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 6d4c318 commit d21ff7d

4 files changed

Lines changed: 113 additions & 2 deletions

File tree

‎.github/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ application. Schemas are generated from Kotlin (or Java) classes by
2727

2828
> **7.0.0 is not released yet.** There is a `7.0.0-SNAPSHOT` to try, published to Javalin's
2929
> Reposilite. See [#7](https://github.com/javalin/javalin-graphql/issues/7) for the release
30-
> and Maven Central discussion.
30+
> and Maven Central discussion, and the [changelog](../CHANGELOG.md) for what is in it.
3131
3232
Add the dependency:
3333

‎.github/workflows/deploy.yml‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,33 @@ jobs:
2626
- name: Set up Gradle
2727
uses: gradle/actions/setup-gradle@v4
2828

29+
# The build derives the version from the tag, so a tag that is not a version would be
30+
# published verbatim. Reject it before anything is built.
31+
- name: Check the tag is a version tag
32+
if: github.ref_type == 'tag'
33+
run: |
34+
if [[ ! "$GITHUB_REF_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.]+)?$ ]]; then
35+
echo "::error::Tag '$GITHUB_REF_NAME' is not a version tag (expected vMAJOR.MINOR.PATCH)."
36+
exit 1
37+
fi
38+
2939
- name: Read version
3040
id: version
3141
run: echo "value=$(./gradlew -q printVersion)" >> "$GITHUB_OUTPUT"
3242

43+
# If the derivation ever falls back to the snapshot default on a tag build — a missing
44+
# GITHUB_REF_TYPE, a checkout that lost the tag, a change to build.gradle.kts — this run
45+
# would quietly overwrite a snapshot instead of releasing. Fail instead.
46+
- name: Check the version matches the tag
47+
if: github.ref_type == 'tag'
48+
run: |
49+
expected="${GITHUB_REF_NAME#v}"
50+
actual="${{ steps.version.outputs.value }}"
51+
if [[ "$actual" != "$expected" ]]; then
52+
echo "::error::Tag '$GITHUB_REF_NAME' would publish '$actual', expected '$expected'."
53+
exit 1
54+
fi
55+
3356
# A manual run may only publish a snapshot; releasing is what the tag is for.
3457
- name: Refuse to release without a tag
3558
if: github.event_name == 'workflow_dispatch' && !endsWith(steps.version.outputs.value, '-SNAPSHOT')

‎CHANGELOG.md‎

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Changelog
2+
3+
All notable changes to this project are documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this
6+
project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). The major version
7+
tracks Javalin's: 7.x targets Javalin 7.x. Releases up to 5.x predate this file.
8+
9+
## [Unreleased]
10+
11+
## [7.0.0] - unreleased
12+
13+
The first release for Javalin 7 and graphql-kotlin 10. Everything under *Changed* and *Removed*
14+
is a breaking change; the README has a
15+
[migration guide](.github/README.md#migrating-from-5x) and `docs/adr` has the reasoning.
16+
17+
### Added
18+
19+
- Subscriptions are served over the
20+
[graphql-transport-ws](https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md)
21+
protocol: `connection_init` / `connection_ack`, `ping` / `pong`, `subscribe` with an operation
22+
id, `next`, `error`, `complete`, and the close codes 4400, 4401, 4409 and 4429 (ADR-002).
23+
- Several subscriptions can run concurrently on one connection, each cancellable by id with
24+
`complete`, and all of them are cancelled when the socket closes or the server stops.
25+
- `disableGraphiQL()`, for an application that does not want to publish a schema explorer.
26+
- `Automatic-Module-Name: io.javalin.community.graphql`, so a modular application can
27+
`requires` the plugin ([#5](https://github.com/javalin/javalin-graphql/issues/5), ADR-004).
28+
- Architecture decision records under `docs/adr`.
29+
- Continuous integration: build and test on JDK 17 and 21 across Linux, macOS and Windows,
30+
plus detekt.
31+
- The published version is derived from the release tag.
32+
33+
### Changed
34+
35+
- Javalin 7.2.2, graphql-kotlin 10.2.0, JVM baseline 17.
36+
- `config.plugins.register(...)` is now `config.registerPlugin(...)`.
37+
- The context is graphql-java's map-like `GraphQLContext` instead of a type of yours, and a
38+
resolver reads it from the `DataFetchingEnvironment` rather than receiving it as a parameter
39+
(ADR-001). `GraphQLPluginBuilder` lost its context type parameter.
40+
- The context factories are now optional constructor arguments of `GraphQLPluginBuilder`, and
41+
the constructor is annotated `@JvmOverloads` so Java can leave them out.
42+
- `GraphQLPluginBuilder.add(...)` is now `addPackage(...)`, and at least one package is
43+
required.
44+
- Subscription resolvers return a kotlinx `Flow` instead of a reactive-streams `Publisher`;
45+
Reactor is no longer a dependency.
46+
- GraphiQL is pinned to 4.1.2 with React 18.3.1, both by version and by SRI hash, and its
47+
fetcher now points at the subscription WebSocket as well as the POST endpoint.
48+
- Payloads are parsed without graphql-kotlin's sealed types, so the plugin works with whatever
49+
`JsonMapper` the application configured (ADR-003).
50+
- The public API dependencies are exposed as `api` rather than `implementation`, so the
51+
examples in the README compile against the artifact.
52+
- The Kotlin sources moved from `src/main/java` to `src/main/kotlin`.
53+
54+
### Removed
55+
56+
- `GraphQLOptions`, together with `GraphQLPluginBuilder.create(options)` and the
57+
`GraphQLPlugin(options)` constructor. `GraphQLPluginBuilder` is the only entry point.
58+
- `middleHandler`, `wsMiddleHandler`, `setMiddleHandler`, `setWSMiddleHandler` and the
59+
`context` argument of `GraphQLOptions`: nothing ever read them, so a `middleHandler` set to
60+
authorize requests was silently dropped. Javalin's `before` and `beforeWs` do that job.
61+
- `GraphQLRun` — use `GraphQLRequestHandler.executeSubscription`.
62+
- `JavalinDataLoaderRegistryFactory` — use graphql-kotlin's `KotlinDataLoaderRegistryFactory`.
63+
- The ad-hoc 5.x WebSocket exchange (a bare query frame answered with bare result data).
64+
65+
### Fixed
66+
67+
- A subscription no longer pins a Jetty thread for its whole lifetime, and stopping the server
68+
cancels the ones still running instead of leaking their coroutines.
69+
- A malformed payload is answered with a 400 over HTTP and a 4400 close over WebSocket instead
70+
of a 500 or a dropped connection.
71+
- A resolver that throws is reported as a protocol `error` frame for its operation instead of
72+
tearing down the whole connection.
73+
- GraphiQL loaded unversioned scripts from a CDN, so it broke as soon as upstream released an
74+
incompatible major, and it requested a `renderExample.js` that does not exist.
75+
- Building the plugin without registering a package now fails saying so, instead of scanning
76+
the package `kotlin.Unit`, which is a class and matches nothing.
77+
78+
[Unreleased]: https://github.com/javalin/javalin-graphql/compare/v7.0.0...HEAD
79+
[7.0.0]: https://github.com/javalin/javalin-graphql/releases/tag/v7.0.0

‎build.gradle.kts‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,16 @@ detekt {
1212
}
1313

1414
group = "io.javalin.community.graphql"
15-
version = "7.0.0-SNAPSHOT"
15+
16+
// The published version is the tag the release workflow runs on: v7.0.0 publishes 7.0.0.
17+
// Anywhere else — a developer machine, a branch build, a manual snapshot publish — it is the
18+
// snapshot below, so nothing can release by accident. GITHUB_REF_TYPE is what distinguishes
19+
// the two: on a branch push GITHUB_REF_NAME is the branch name. deploy.yml cross-checks both.
20+
version = System.getenv("GITHUB_REF_NAME")
21+
?.takeIf { System.getenv("GITHUB_REF_TYPE") == "tag" }
22+
?.removePrefix("v")
23+
?.takeIf { it.isNotBlank() }
24+
?: "7.0.0-SNAPSHOT"
1625

1726
repositories {
1827
mavenCentral()

0 commit comments

Comments
 (0)