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
55 changes: 55 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,22 @@ jobs:
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v6

# The tag names the release; gradle.properties names the artifacts. Nothing tied the two
# together, and the failure is asymmetric: tagging ABOVE the version is self-limiting
# because Central rejects a duplicate version at validation, but tagging BELOW it (v0.0.7
# while the file already says 0.0.8) publishes 0.0.8 permanently, auto-released, with the
# tag and the artifact disagreeing forever and no error anywhere. Check it first, before
# anything is downloaded, tested or published.
- name: Tag must match gradle.properties
run: |
version=$(sed -n 's/^version=//p' gradle.properties)
[ -n "$version" ] || { echo "::error::no version= in gradle.properties"; exit 1; }
if [ "v$version" != "${GITHUB_REF_NAME}" ]; then
echo "::error::tag ${GITHUB_REF_NAME} does not match gradle.properties version $version (expected v$version) — nothing published"
exit 1
fi
echo "tag ${GITHUB_REF_NAME} matches version $version"

# Fetch every platform's payload — needed for the natives classifier jars and to run the
# tests (which use the host's, linux-x86_64, payload).
- name: Download pinned Slang natives (all platforms)
Expand All @@ -57,15 +73,54 @@ jobs:
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY }}
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_PASSWORD }}

# Which Slang a release bundles is the first thing anyone wants from these notes, and
# --generate-notes alone never says it: it lists merged PRs, and a version bump reads as
# one more line among them. Both versions are derived here rather than written by hand,
# so they cannot drift from what actually shipped.
- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
slang=$(sed -n 's/^val slangVersion = "\(.*\)"$/\1/p' natives/build.gradle.kts)
floor=$(sed -n 's/.*PINNED_SLANG_VERSION = "\(.*\)".*/\1/p' \
slang/src/main/java/io/github/refux/slang/loader/SlangLibrary.java)
classifiers=$(ls natives/manifests/*.json | xargs -n1 basename | sed 's/\.json$//' \
| sort | sed 's/^/`/; s/$/`/' | paste -sd, - | sed 's/,/, /g')
[ -n "$slang" ] && [ -n "$floor" ] || { echo "::error::could not derive the Slang versions"; exit 1; }

# The two are equal after a full regeneration and legitimately differ after a
# natives-only bump, because PINNED_SLANG_VERSION is a floor rather than a lockstep.
# Saying which is which matters more when they diverge, so spell it out then.
if [ "$slang" = "$floor" ]; then
provenance="Bundles the official **Slang \`$slang\`** binaries, unmodified, and the bindings are generated against that same release."
else
provenance="Bundles the official **Slang \`$slang\`** binaries, unmodified. The bindings are generated against Slang \`$floor\` and run against these newer binaries, which Slang's append-only public ABI guarantees."
fi

notes=$(cat <<EOF
$provenance

| | |
|---|---|
| Slang binaries bundled | \`$slang\` |
| Bindings generated against | \`$floor\` |
| Natives classifiers | $classifiers |

\`SlangLibrary.PINNED_SLANG_VERSION\` is a **minimum**, not a pin: a newer Slang works, an
older one does not. Every jar records what it binds, without being run:

\`\`\`
unzip -p slang-java-${GITHUB_REF_NAME#v}.jar META-INF/MANIFEST.MF
\`\`\`
EOF
)

# Idempotent: drop a prior release for this tag (e.g. a re-tagged release) but keep the
# tag itself, then create fresh.
gh release delete "${GITHUB_REF_NAME}" --yes || true
gh release create "${GITHUB_REF_NAME}" \
--title "${GITHUB_REF_NAME}" \
--notes "$notes" \
--generate-notes \
slang/build/libs/*.jar \
natives/build/libs/slang-java-natives-*-{linux,macos,windows}-*.jar
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ walkthrough as its acceptance test, and Java-implemented COM upcalls serving imp
the bump workflow from it; that path is off on the schedule until the reusable-workflow
permission chain has been proven by one real run (rationale in the workflow header).
- Verify hand-written struct layouts: `tools/abi-probe.cpp` (build/run instructions in its header)
- Release: push a tag matching the version in `slang/build.gradle.kts` (e.g. `v0.0.1`) —
- Release: push a tag matching `version` in `gradle.properties` (e.g. `v0.0.1`) — the
release workflow now refuses to publish if the two disagree —
`.github/workflows/release.yml` runs the tests against the pinned binaries, publishes
`io.github.refux:slang-java` to Maven Central (auto-released), and creates the GitHub Release.
Requires repo secrets `MAVEN_CENTRAL_USERNAME`/`MAVEN_CENTRAL_PASSWORD` and
Expand Down