Skip to content

Commit 41eca03

Browse files
pditommasoclaudebentsherman
authored
Add automated release job to GitHub Actions workflow (#6401) [ci skip]
Signed-off-by: Paolo Di Tommaso <[email protected]> Co-authored-by: Claude <[email protected]> Co-authored-by: Ben Sherman <[email protected]>
1 parent a5756da commit 41eca03

File tree

5 files changed

+208
-11
lines changed

5 files changed

+208
-11
lines changed

.github/workflows/build.yml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,69 @@ jobs:
229229
env:
230230
GITHUB_TOKEN: ${{ secrets.AUTOMATION_GITHUB_TOKEN }}
231231
GRADLE_OPTS: '-Dorg.gradle.daemon=false'
232+
233+
release:
234+
if: ${{ contains(needs.build.outputs.commit_message, '[release]') }}
235+
needs: [build, test]
236+
runs-on: ubuntu-latest
237+
timeout-minutes: 10
238+
permissions:
239+
actions: write
240+
contents: write
241+
packages: write
242+
pull-requests: write
243+
issues: write
244+
steps:
245+
- name: Checkout
246+
uses: actions/checkout@v4
247+
with:
248+
fetch-depth: 0
249+
submodules: true
250+
ref: ${{ github.head_ref || github.ref_name }}
251+
252+
- name: Setup Java 17
253+
uses: actions/setup-java@v4
254+
with:
255+
java-version: 17
256+
distribution: 'temurin'
257+
architecture: x64
258+
cache: gradle
259+
260+
- name: Configure Git
261+
run: |
262+
git config --global user.name "${{ github.event.pusher.name || github.actor }}"
263+
git config --global user.email "${{ github.event.pusher.email || format('{0}@users.noreply.github.com', github.actor) }}"
264+
265+
- name: Docker Login to Docker Hub
266+
uses: docker/login-action@v3
267+
with:
268+
username: ${{ vars.DOCKERHUB_USERNAME }}
269+
password: ${{ secrets.DOCKERHUB_TOKEN }}
270+
271+
- name: Docker Login to Seqera public CR
272+
uses: docker/login-action@v3
273+
with:
274+
registry: "public.cr.seqera.io"
275+
username: ${{ vars.SEQERA_PUBLIC_CR_USERNAME }}
276+
password: ${{ secrets.SEQERA_PUBLIC_CR_PASSWORD }}
277+
278+
- name: Run release
279+
run: |
280+
echo "Starting release process..."
281+
echo "npr.apiUrl=$NPR_API_URL" >> gradle.properties
282+
echo "npr.apiKey=$NPR_API_KEY" >> gradle.properties
283+
bash release.sh
284+
env:
285+
GRADLE_OPTS: '-Dorg.gradle.daemon=false'
286+
AWS_JAVA_V1_DISABLE_DEPRECATION_ANNOUNCEMENT: 'true'
287+
# credentials to pubslish nextflow assets
288+
NXF_AWS_ACCESS: ${{ vars.NXF_AWS_ACCESS }}
289+
NXF_AWS_SECRET: ${{ secrets.NXF_AWS_SECRET }}
290+
# credentials to publish maven libraries
291+
AWS_ACCESS_KEY_ID: ${{ vars.SEQERA_MAVEN_ACCESS_KEY }}
292+
AWS_SECRET_ACCESS_KEY: ${{ secrets.SEQERA_MAVEN_SECRET_KEY }}
293+
# plugin registry
294+
NPR_API_URL: ${{ vars.NPR_API_URL }}
295+
NPR_API_KEY: ${{ secrets.NPR_API_KEY }}
296+
# GitHub secrets
297+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

CLAUDE.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ The project follows a modular architecture with a plugin-based system for cloud
8989
### Git conventions
9090

9191
- Commit should be signed by adding a `Signed-off-by` line to the commit message as shown below, or by using the `-s` option (see CONTRIBUTING.md for details)
92+
- Special commit message tags:
93+
- `[ci skip]` - Skip the execution of CI tests
94+
- `[ci fast]` - Run only unit tests and skip integration tests
95+
- `[e2e stage]` - Run end-to-end tests vs Seqera platform stage environment
96+
- `[e2e prod]` - Same but against production platform
97+
- `[release]` - Trigger release process
9298

9399
## Important Files
94100
- `VERSION`: Define the current version number
@@ -97,3 +103,29 @@ The project follows a modular architecture with a plugin-based system for cloud
97103
- `build.gradle`: Root build configuration with multi-module setup
98104
- `settings.gradle`: Gradle project structure definition
99105
- `plugins/*/VERSION`: Define the version of the corresponding plugin sub-project.
106+
107+
## Release process
108+
109+
Follow these actions to make a new release:
110+
111+
- Update the `changelog.txt` file in each plugin sub-project (if any change has been done).
112+
- Update the `VERSION` file in in each plugin sub-project.
113+
Use a semantic version number depending the impact of the change, or do not change
114+
if no changes have been done to the plugin.
115+
- Update `nextflowVersion` attribute in the `build.gradle` file for plugins requiring specific
116+
Nextflow versions.
117+
- Commit the version and changelog files changes independently for each plugin. Use as commit
118+
message the template `Bump plugin-name@version` e.g. `Bump [email protected].
119+
- Update `VERSION` file in the project root using a calendar-like versioning scheme. Versions in the 4-th and 10-th month are "stable releases", e.g. `25.10.0`, while versions in all other months are "edge releases", e.g. `25.09.0-edge`.
120+
- Update the project root `changelog.txt` with changes since the past release. Use the git log
121+
command to determine what changed e.g. `git log v<PREVIOUS VERSION>..`
122+
- Run `make releaseInfo` to update the version number and generate checksums.
123+
- Run this command to stage for commit the release files:
124+
```
125+
git add VERSION changelog.txt nextflow nextflow.md5 nextflow.sha1 nextflow.sha256
126+
```
127+
- Make a commit using the `[release]` tag in the comment and push it upstream to trigger the release automation with GitHub action:
128+
```
129+
git commit -m "[release] Nextflow version 25.09.0-edge"
130+
git push origin master
131+
```

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ compile:
3434
assemble:
3535
./gradlew buildInfo compile assemble
3636

37+
releaseInfo:
38+
./gradlew releaseInfo
39+
3740
check:
3841
./gradlew check
3942

build.gradle

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,24 @@ task buildInfo { doLast {
208208
commitId=${project.property('commitId')}
209209
""".stripIndent()
210210

211+
212+
// -- create plugins-info file
213+
def plugins = []
214+
new File(rootProject.rootDir, 'plugins')
215+
.eachDir { if(it.name.startsWith('nf-')) plugins << project(":plugins:${it.name}") }
216+
217+
def meta = plugins .collect { "$it.name@$it.version" }
218+
file('modules/nextflow/src/main/resources/META-INF/plugins-info.txt').text = meta.toSorted().join('\n')
219+
}}
220+
221+
/*
222+
* Update release information in nextflow wrapper and dockerfile
223+
*/
224+
task releaseInfo { doLast {
225+
211226
// -- update 'nextflow' wrapper
212-
file0 = file('nextflow')
213-
src = file0.text
227+
def file0 = file('nextflow')
228+
def src = file0.text
214229
src = src.replaceAll(/NXF_VER\=\$\{NXF_VER:-'.*'\}/, 'NXF_VER=\\${NXF_VER:-\'' + version + '\'}')
215230
file0.text = src
216231

@@ -219,14 +234,6 @@ task buildInfo { doLast {
219234
src = file0.text
220235
src = src.replaceAll(/releases\/v[0-9a-zA-Z_\-\.]+\//, "releases/v$version/" as String)
221236
file0.text = src
222-
223-
// -- create plugins-info file
224-
def plugins = []
225-
new File(rootProject.rootDir, 'plugins')
226-
.eachDir { if(it.name.startsWith('nf-')) plugins << project(":plugins:${it.name}") }
227-
228-
def meta = plugins .collect { "$it.name@$it.version" }
229-
file('modules/nextflow/src/main/resources/META-INF/plugins-info.txt').text = meta.toSorted().join('\n')
230237
}}
231238

232239

@@ -411,10 +418,12 @@ task makeDigest { doLast {
411418
file('nextflow.md5').text = bytesToHex(digest) + '\n'
412419
}}
413420

421+
// Make releaseInfo task automatically run makeDigest after updating versions
422+
releaseInfo.finalizedBy makeDigest
423+
414424

415425
task upload {
416426
dependsOn compile
417-
dependsOn makeDigest
418427
dependsOn coreProjects.publish
419428
}
420429

release.sh

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/bin/bash
2+
#
3+
# Nextflow Release Script
4+
#
5+
# This script performs the complete Nextflow release process including:
6+
# - Building and assembling artifacts
7+
# - Uploading to S3 and Maven repositories
8+
# - Releasing plugins to registry
9+
# - Creating GitHub releases with signed artifacts
10+
#
11+
# REQUIRED SECRETS/ENVIRONMENT VARIABLES FOR GITHUB ACTIONS:
12+
#
13+
# AWS S3 Deployment:
14+
# NXF_AWS_ACCESS - AWS Access Key for deploying to s3://www2.nextflow.io
15+
# NXF_AWS_SECRET - AWS Secret Key for S3 deployment
16+
#
17+
# Maven Repository (Seqera S3-based):
18+
# AWS_ACCESS_KEY_ID - AWS credentials for Maven repository access
19+
# AWS_SECRET_ACCESS_KEY - AWS secret for Maven repository access
20+
#
21+
# GitHub Integration:
22+
# GITHUB_TOKEN - For creating releases and uploading assets
23+
#
24+
# Plugin Registry:
25+
# NPR_API_URL - Nextflow Plugin Registry API URL
26+
# NPR_API_KEY - Nextflow Plugin Registry API key
27+
#
28+
# Container Registry Authentication:
29+
# DOCKERHUB_USERNAME - Docker Hub username for container publishing
30+
# DOCKERHUB_TOKEN - Docker Hub token/password for container publishing
31+
# SEQERA_PUBLIC_CR_PASSWORD - Seqera public container registry password
32+
#
33+
# Usage: Only run when commit message contains '[release]'
34+
#
35+
set -e
36+
37+
echo "=== Starting Nextflow Release Process ==="
38+
echo "Commit message: ${GITHUB_HEAD_COMMIT_MESSAGE:-$(git log -1 --pretty=format:'%s')}"
39+
40+
# Check required environment variables
41+
echo "=== Checking required environment variables ==="
42+
REQUIRED_VARS=(
43+
"NXF_AWS_ACCESS"
44+
"NXF_AWS_SECRET"
45+
"AWS_ACCESS_KEY_ID"
46+
"AWS_SECRET_ACCESS_KEY"
47+
"GITHUB_TOKEN"
48+
"NPR_API_URL"
49+
"NPR_API_KEY"
50+
)
51+
52+
MISSING_VARS=()
53+
for var in "${REQUIRED_VARS[@]}"; do
54+
if [ -z "${!var}" ]; then
55+
MISSING_VARS+=("$var")
56+
else
57+
echo "$var is set"
58+
fi
59+
done
60+
61+
if [ ${#MISSING_VARS[@]} -ne 0 ]; then
62+
echo "❌ ERROR: The following required environment variables are not set:"
63+
for var in "${MISSING_VARS[@]}"; do
64+
echo " - $var"
65+
done
66+
echo "Please ensure all required environment variables are configured before running the release."
67+
exit 1
68+
fi
69+
70+
echo "✅ All required environment variables are set"
71+
72+
echo "🔧 === Step 1: Assemble, upload, and deploy ==="
73+
make assemble upload deploy
74+
echo "✅ Step 1 completed successfully"
75+
echo ""
76+
77+
echo "🔌 === Step 2: Release plugins ==="
78+
make release-plugins
79+
echo "✅ Step 2 completed successfully"
80+
echo ""
81+
82+
echo "🚀 === Step 3: Final release ==="
83+
make release
84+
echo "✅ Step 3 completed successfully"
85+
echo ""
86+
87+
echo "🎉 === Release process completed successfully ==="

0 commit comments

Comments
 (0)