-
Notifications
You must be signed in to change notification settings - Fork 1
150 lines (136 loc) · 6.6 KB
/
Copy pathrelease.yml
File metadata and controls
150 lines (136 loc) · 6.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
name: Release
# Sends a deployment to the Maven Central Portal. It is not released automatically: the deployment
# waits in the Portal until someone looks at it and presses publish. A pending deployment can be
# dropped; a released one cannot be unpublished, and that asymmetry is the whole reason for the
# manual step.
on:
push:
tags: ['v*']
workflow_dispatch:
inputs:
version:
description: 'Version to publish, for example 0.0.1-alpha.1'
required: true
type: string
permissions:
contents: read
id-token: write
attestations: write
# To read whether this commit's CI and tmux matrix passed.
actions: read
jobs:
publish:
# A tag push is already a tag ref by construction; a dispatch is refused unless the ref it runs
# against is one too, so signing and Central secrets are never reachable from a branch.
if: github.event_name == 'push' || startsWith(github.ref, 'refs/tags/v')
# RELEASING.md records the one-time step this file cannot do: create this environment with a
# tag-only deployment policy and a required reviewer, and move the signing and Central secrets
# into it. A workflow condition can refuse a branch; only the environment protects the secrets
# themselves if that condition is ever wrong.
environment: release
runs-on: ubuntu-latest
# check alone takes about twelve minutes on a hosted runner; the upload follows it.
timeout-minutes: 30
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
# This job checks on one JDK and one tmux. The commit is released on what it proved everywhere:
# CI on JDK 25 and 27, and every supported tmux lane, each for exactly this commit; macOS is reported only.
# Nothing is re-run here: a workflow still running, or never run for this commit, refuses the
# release, which is started again once it has passed.
- name: Require this commit's CI and tmux matrix to have passed
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
run: |
for workflow in ci.yml tmux-matrix.yml; do
passed=$(gh run list --workflow "$workflow" --commit "$GITHUB_SHA" --limit 50 \
--json conclusion --jq 'map(select(.conclusion == "success")) | length')
if [ "$passed" -lt 1 ]; then
echo "::error::$workflow has no successful run for $GITHUB_SHA; let it pass, then release again"
exit 1
fi
echo "$workflow passed on $GITHUB_SHA"
done
- name: Install tmux
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends -y tmux
- uses: actions/setup-java@de7274f081f381c8f8158605e0321c36c376e2e6 # v6
with:
distribution: temurin
java-version: '25'
- uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6
with:
validate-wrappers: true
# A tag names the version; a manual run states it. Either way it is passed in rather than
# committed, so no commit ever carries a release version in gradle.properties.
- name: Work out the version
id: version
env:
REF_NAME: ${{ github.ref_name }}
INPUT_VERSION: ${{ inputs.version }}
run: |
if [ -n "$INPUT_VERSION" ]; then
version="$INPUT_VERSION"
else
version="${REF_NAME#v}"
fi
# Validated rather than trusted. This value reaches a command line, and a tag name is
# whatever the person pushing the tag typed; anything outside this shape is not a version
# this project publishes. It also catches the spellings Maven orders wrongly — see
# RELEASING.md for why 0.0.1-a.1 sorts after 0.0.1.
case "$version" in
*-SNAPSHOT) echo "::error::refusing to release a snapshot: $version"; exit 1 ;;
esac
printf '%s' "$version" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+(-(alpha|beta|milestone|rc)\.[0-9]+)?$' || {
echo "::error::not a version this project publishes: $version"
exit 1
}
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "releasing $version"
# The gate runs before anything is uploaded. A deployment can be dropped, but a broken one
# should never get as far as needing to be.
- name: Check
env:
VERSION: ${{ steps.version.outputs.version }}
run: ./gradlew check -PlibtmuxVersion="$VERSION" --stacktrace
# A signing key may or may not carry a passphrase, and an unset secret arrives as an empty
# string rather than as nothing. The publisher does not treat blank as absent, so an empty
# value is offered as the passphrase and decryption fails. Set it only when there is one.
- name: Carry the passphrase only if the key has one
env:
PASSPHRASE: ${{ secrets.SIGNING_PASSWORD }}
run: |
if [ -n "$PASSPHRASE" ]; then
echo "ORG_GRADLE_PROJECT_signingInMemoryKeyPassword=$PASSPHRASE" >> "$GITHUB_ENV"
echo "signing key has a passphrase"
else
echo "signing key has no passphrase"
fi
- name: Publish to the Central Portal
env:
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.CENTRAL_PORTAL_USERNAME }}
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.CENTRAL_PORTAL_PASSWORD }}
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY }}
VERSION: ${{ steps.version.outputs.version }}
run: ./gradlew publishToMavenCentral -PlibtmuxVersion="$VERSION" --stacktrace
# The Portal records the files. This records which commit and workflow
# produced them. A tag can be moved; the attestation cannot.
- name: Attest the published jars
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
with:
subject-path: |
libtmux/build/libs/*.jar
libtmux-jackson/build/libs/*.jar
libtmux-junit5/build/libs/*.jar
libtmux-kotlin/build/libs/*.jar
libtmux-mcp/build/libs/*.jar
libtmux-workspace/build/libs/*.jar
libtmux-workspace-cli/build/libs/*.jar
libtmux-scala/build/libs/*.jar
libtmux-scala-cats/build/libs/*.jar
libtmux-scala-ox/build/libs/*.jar
libtmux-bom/build/publications/maven/pom-default.xml
- name: What to do next
run: |
echo "::notice::Deployment uploaded. Open https://central.sonatype.com/publishing/deployments and publish or drop it."