Skip to content
Open
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
125 changes: 125 additions & 0 deletions .github/scripts/e2e-launch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#
# Copyright 2013-2026, Seqera Labs
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
set -e

# Build a snapshot Nextflow launcher container and trigger the Seqera Platform
# showcase e2e test, surfacing the dispatched run URL via step outputs/summary.
# ENVIRONMENT ('production'|'staging') is set by the workflow; if unset it falls
# back to grepping the commit message for '[e2e prod]'.
SHOWCASE_REPO=${SHOWCASE_REPO:-'seqeralabs/showcase-automation'}
REPO_ROOT="$(git rev-parse --show-toplevel)"
# docker build context: Dockerfile + assembled runtime (installScratch targets its .nextflow/)
CTX="$REPO_ROOT/.github/test-e2e"

# cleanup
rm -rf "$CTX/.nextflow" && mkdir -p "$CTX/.nextflow"
# copy nextflow dependencies
(cd "$REPO_ROOT"
export NXF_PLUGINS_DIR=$PWD/build/plugins
make releaseInfo assemble installScratch
)

# copy nextflow plugins
cp -r "$REPO_ROOT/build/plugins" "$CTX/.nextflow/"
# copy nextflow launcher script
cp "$REPO_ROOT/nextflow" "$CTX/" && chmod +x "$CTX/nextflow"
cp "$REPO_ROOT/modules/nextflow/src/main/resources/META-INF/build-info.properties" "$CTX/"
source "$CTX/build-info.properties"

if [ -z "$version" ]; then
echo "Error: version is empty or missing"; exit 1
fi
if [ -z "$build" ]; then
echo "Error: build is empty or missing"; exit 1
fi
if [ -z "$commitId" ]; then
echo "Error: commitId is empty or missing"; exit 1
fi

echo "version : $version"
echo "build : $build"
echo "commit id: $commitId"

#
# build a scratch container image with assembled nextflow runtime and plugins
#
tag=${version}-${commitId}
base=${base:-'public.cr.seqera.io/platform/nf-launcher:j17-base'}
repository=${repository:-'public.cr.seqera.io/snapshots/nextflow-scratch'}
image=${repository}:${tag}

docker buildx build \
--platform linux/amd64 \
--push \
--progress=plain \
--tag ${image} \
--build-arg TARGETPLATFORM=linux/amd64 \
"$CTX"
echo "Nextflow snapshots launcher image $image"

#
# Create an ephemeral container with the scratch image and base Platform launcher image
#
launcher=$(wave -i ${base} --include ${image} --platform linux/amd64 --config-env NXF_HOME=/.nextflow --config-env NXF_SYNTAX_PARSER=v1)
echo "Running Platform tests using image launcher: $launcher"

# determine the e2e environment: prefer $ENVIRONMENT, else fall back to the commit message
if [ -z "$ENVIRONMENT" ]; then
[ -z "$COMMIT_MESSAGE" ] && COMMIT_MESSAGE=$(git show -s --format='%s')
if echo "$COMMIT_MESSAGE" | grep -q "\[e2e prod\]"; then
ENVIRONMENT="production"
else
ENVIRONMENT="staging"
fi
fi

#
# Launch the showcase automation
# see https://github.com/seqeralabs/showcase-automation/
#
workflow_file="seqera-showcase-${ENVIRONMENT}.yml"
echo "Launching ${workflow_file} in ${SHOWCASE_REPO}"
dispatch_time=$(date -u +%Y-%m-%dT%H:%M:%SZ)
gh workflow run "${workflow_file}" --repo "${SHOWCASE_REPO}" -f launch_container=${launcher}

# `gh workflow run` does not return the dispatched run, so poll for the newest
# run created at/after the dispatch time (falling back to the workflow runs page)
run_url=""
for attempt in $(seq 1 12); do
sleep 5
run_url=$(gh run list --repo "${SHOWCASE_REPO}" --workflow "${workflow_file}" --event workflow_dispatch --limit 10 \
--json url,createdAt --jq "[.[] | select(.createdAt >= \"${dispatch_time}\")] | sort_by(.createdAt) | last | .url // empty" 2>/dev/null || true)
[ -n "$run_url" ] && break
done
[ -z "$run_url" ] && run_url="https://github.com/${SHOWCASE_REPO}/actions/workflows/${workflow_file}"
echo "Showcase run: $run_url"

# expose results to the calling workflow (step outputs) and the run page (summary)
if [ -n "$GITHUB_OUTPUT" ]; then
{
echo "environment=${ENVIRONMENT}"
echo "launcher_image=${launcher}"
echo "showcase_url=${run_url}"
} >> "$GITHUB_OUTPUT"
fi
if [ -n "$GITHUB_STEP_SUMMARY" ]; then
{
echo "### e2e showcase launched against \`${ENVIRONMENT}\`"
echo "- Run: [${run_url}](${run_url})"
echo "- Launcher image: \`${launcher}\`"
echo "> CI only launches the test — open the run above to confirm it passed."
} >> "$GITHUB_STEP_SUMMARY"
fi
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
154 changes: 102 additions & 52 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ on:
pull_request:
types: [opened, reopened, synchronize]
workflow_dispatch:
inputs:
e2e:
description: 'Launch the e2e showcase test after build (same as the [e2e ...] commit tag)'
type: choice
options:
- 'none'
- 'staging'
- 'production'
default: 'none'
release:
description: 'Run the release process after build + tests (same as the [release] commit tag)'
type: boolean
default: false

permissions:
contents: read
Expand Down Expand Up @@ -164,7 +177,7 @@ jobs:
export GOOGLE_APPLICATION_CREDENTIALS="$RUNNER_TEMP/google_credentials.json"
fi
make clean assemble install
bash test-ci.sh
bash .github/scripts/test-ci.sh
env:
TEST_JDK: ${{ matrix.java_version }}
TEST_MODE: ${{ matrix.test_mode }}
Expand Down Expand Up @@ -198,59 +211,38 @@ jobs:
validation-tests.tar.gz
integration-tests.tar.gz

# Launch the e2e showcase test once the build is green. Triggered by the
# [e2e stage]/[e2e prod] commit tag, or the workflow_dispatch `e2e` input.
# All logic lives in the reusable .github/workflows/e2e.yml workflow.
test-e2e:
if: ${{ contains(needs.build.outputs.commit_message,'[e2e stage]') || contains(needs.build.outputs.commit_message,'[e2e prod]') }}
needs: build
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 1
submodules: true
persist-credentials: false

- name: Setup Java 17
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
java-version: 17
distribution: 'temurin'
architecture: x64
cache: gradle

- name: Setup env
env:
NEEDS_BUILD_OUTPUTS_COMMIT_MESSAGE: ${{ needs.build.outputs.commit_message }}
run: |
wget -q -O wave https://github.com/seqeralabs/wave-cli/releases/download/v1.4.1/wave-1.4.1-linux-x86_64
chmod +x wave
mv wave /usr/local/bin/
# Use heredoc-style delimiter so multi-line / quote-containing
# commit messages survive intact (run.sh greps for `[e2e prod]`).
{
echo "COMMIT_MESSAGE<<NXF_EOF"
echo "$NEEDS_BUILD_OUTPUTS_COMMIT_MESSAGE"
echo "NXF_EOF"
} >> "$GITHUB_ENV"

- name : Docker Login to Seqera public CR
uses : docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with :
registry : "public.cr.seqera.io"
username : "public-cr-admin"
password : ${{ secrets.SEQERA_PUBLIC_CR_PASSWORD }}

- name: Launch tests
run: |
cd test-e2e
bash run.sh
env:
GITHUB_TOKEN: ${{ secrets.AUTOMATION_GITHUB_TOKEN }}
GRADLE_OPTS: '-Dorg.gradle.daemon=false'
needs: build
if: >-
contains(needs.build.outputs.commit_message, '[e2e stage]') ||
contains(needs.build.outputs.commit_message, '[e2e prod]') ||
( github.event_name == 'workflow_dispatch' && inputs.e2e != 'none' )
uses: ./.github/workflows/e2e.yml
with:
# inputs.e2e is the dispatch choice ('' on push/PR, so it falls through)
environment: ${{ inputs.e2e || (contains(needs.build.outputs.commit_message, '[e2e prod]') && 'production' || 'staging') }}
secrets:
SEQERA_PUBLIC_CR_PASSWORD: ${{ secrets.SEQERA_PUBLIC_CR_PASSWORD }}
AUTOMATION_GITHUB_TOKEN: ${{ secrets.AUTOMATION_GITHUB_TOKEN }}

# Run the release once build is green and tests pass. Triggered by the
# [release] commit tag, or the workflow_dispatch `release` input. The dispatch
# path is limited to the same branches the push trigger allows, so a release
# can't be kicked off from an arbitrary feature branch.
release:
if: ${{ always() && contains(needs.build.outputs.commit_message, '[release]') && needs.build.result == 'success' && (needs.test.result == 'success' || needs.test.result == 'skipped') }}
if: >-
always() &&
needs.build.result == 'success' &&
(needs.test.result == 'success' || needs.test.result == 'skipped') &&
( contains(needs.build.outputs.commit_message, '[release]') ||
( github.event_name == 'workflow_dispatch' && inputs.release &&
( github.ref_name == 'master' ||
startsWith(github.ref_name, 'test') ||
startsWith(github.ref_name, 'dev') ||
startsWith(github.ref_name, 'STABLE-') ) ) )
needs: [build, test]
runs-on: ubuntu-latest
timeout-minutes: 10
Expand Down Expand Up @@ -301,7 +293,7 @@ jobs:
echo "Starting release process..."
echo "npr.apiUrl=$NPR_API_URL" >> gradle.properties
echo "npr.apiKey=$NPR_API_KEY" >> gradle.properties
bash release.sh
bash .github/scripts/release.sh
env:
GRADLE_OPTS: '-Dorg.gradle.daemon=false'
AWS_JAVA_V1_DISABLE_DEPRECATION_ANNOUNCEMENT: 'true'
Expand All @@ -316,3 +308,61 @@ jobs:
NPR_API_KEY: ${{ secrets.NPR_API_KEY }}
# GitHub secrets
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# Always-on consolidated summary so the run page shows, at a glance, what ran,
# whether it passed, and (for e2e) the showcase run URL to follow up on.
summary:
if: ${{ always() }}
needs: [build, test, test-e2e, release]
runs-on: ubuntu-latest
steps:
- name: Write CI summary
env:
BUILD_RESULT: ${{ needs.build.result }}
TEST_RESULT: ${{ needs.test.result }}
E2E_RESULT: ${{ needs.test-e2e.result }}
RELEASE_RESULT: ${{ needs.release.result }}
E2E_ENV: ${{ needs.test-e2e.outputs.environment }}
E2E_LAUNCHER: ${{ needs.test-e2e.outputs.launcher_image }}
E2E_URL: ${{ needs.test-e2e.outputs.showcase_url }}
run: |
icon() {
case "$1" in
success) echo "✅ success" ;;
failure) echo "❌ failure" ;;
cancelled) echo "⚠️ cancelled" ;;
skipped|"") echo "⏭️ skipped" ;;
*) echo "$1" ;;
esac
}

# overall verdict: failure wins (short-circuits), then cancelled, else passed
overall="✅ passed"
for r in "$BUILD_RESULT" "$TEST_RESULT" "$E2E_RESULT" "$RELEASE_RESULT"; do
case "$r" in
failure) overall="❌ failed"; break ;;
cancelled) overall="⚠️ cancelled" ;;
esac
done

{
echo "## Nextflow CI — ${overall}"
echo ""
echo "| Job | Result |"
echo "|---|---|"
echo "| Build + unit tests | $(icon "$BUILD_RESULT") |"
echo "| Integration tests | $(icon "$TEST_RESULT") |"
echo "| e2e showcase | $(icon "$E2E_RESULT") |"
echo "| Release | $(icon "$RELEASE_RESULT") |"
echo ""
} >> "$GITHUB_STEP_SUMMARY"

if [ "$E2E_RESULT" = "success" ] && [ -n "$E2E_URL" ]; then
{
echo "### e2e showcase launched against \`${E2E_ENV}\`"
echo "- Run: [${E2E_URL}](${E2E_URL}) (launcher \`${E2E_LAUNCHER}\`)"
echo "> CI only launches the test — open the run to confirm it passed."
} >> "$GITHUB_STEP_SUMMARY"
elif [ "$E2E_RESULT" = "failure" ]; then
echo "### e2e showcase failed to launch — check the \`test-e2e\` job logs" >> "$GITHUB_STEP_SUMMARY"
fi
41 changes: 0 additions & 41 deletions .github/workflows/claude.yml

This file was deleted.

Loading
Loading