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
85 changes: 85 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# SPDX-FileCopyrightText: 2006-2026 Knut Reinert & Freie Universität Berlin
# SPDX-FileCopyrightText: 2016-2026 Knut Reinert & MPI für molekulare Genetik
# SPDX-License-Identifier: CC0-1.0

# Staged CI: cheap checks -> Linux unit tests -> everything else. A later stage only starts if the earlier ones passed,
# so a formatting error costs one short Lint job instead of a full CI run.
#
# Stage 1 Lint (ci_lint.yml), License (ci_license.yml)
# Stage 2 Linux (ci_linux.yml)
# Stage 3 Coverage, Install, macOS
#
# Runs PR code, therefore only `pull_request`: read-only GITHUB_TOKEN, no secrets for fork PRs. If Lint fails,
# lint_autofix.yml (from the default branch) pushes the formatting fix, which starts CI again.
# The only required status check is "CI result" (plus "Documentation", which stays a separate workflow).

name: CI

on:
push:
branches:
- 'main'
- 'hibf'
pull_request:
workflow_dispatch:

# Replaces the cancel_running_workflows job of the old lint workflow: a new push to a PR cancels all stages.
concurrency:
group: ci-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name != 'push' }}

permissions:
contents: read

jobs:
# Stage 1. As in all of the repository's workflows: on forks, only when started by hand.
lint:
name: Lint
if: github.repository_owner == 'seqan' || github.event_name == 'workflow_dispatch'
uses: ./.github/workflows/ci_lint.yml
license:
name: License
if: github.repository_owner == 'seqan' || github.event_name == 'workflow_dispatch'
uses: ./.github/workflows/ci_license.yml

# Stage 2
linux:
name: Linux
needs: [lint, license]
uses: ./.github/workflows/ci_linux.yml

# Stage 3. Coverage gets the Codecov token; the other stages need no secrets.
coverage:
name: Coverage
needs: linux
uses: ./.github/workflows/ci_coverage.yml
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
install:
name: Install
needs: linux
uses: ./.github/workflows/ci_install.yml
macos:
name: macOS
needs: linux
uses: ./.github/workflows/ci_macos.yml

# The single required check. Required checks cannot simply list the stages: a skipped job reports "Success", and a
# skipped matrix job reports under its unexpanded name. This gate runs always and fails unless every stage
# succeeded (skipped and cancelled count as failure).
result:
name: CI result
if: always() && (github.repository_owner == 'seqan' || github.event_name == 'workflow_dispatch')
needs: [lint, license, linux, coverage, install, macos]
runs-on: ubuntu-latest
steps:
- name: Check stage results
env:
RESULTS: ${{ join(needs.*.result, ' ') }}
run: |
for result in ${RESULTS}; do
if [[ ${result} != success ]]; then
echo "::error::Not every CI stage succeeded: ${RESULTS}"
exit 1
fi
done
21 changes: 7 additions & 14 deletions .github/workflows/ci_coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,12 @@
name: Coverage

on:
push:
branches:
- 'main'
- 'hibf'
pull_request:
types:
- unlabeled
workflow_call:
secrets:
CODECOV_TOKEN:
required: false
workflow_dispatch:

concurrency:
group: coverage-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name != 'push' }}

env:
SHARG_NO_VERSION_CHECK: 1
TZ: Europe/Berlin
Expand All @@ -30,7 +23,7 @@ jobs:
build:
runs-on: ubuntu-latest
name: ${{ matrix.compiler }}
if: github.repository_owner == 'seqan' || github.event_name == 'workflow_dispatch' || github.event.label.name == 'lint'
if: github.repository_owner == 'seqan' || github.event_name == 'workflow_dispatch'
strategy:
fail-fast: false
matrix:
Expand All @@ -39,7 +32,7 @@ jobs:
image: ghcr.io/seqan/${{ matrix.compiler }}
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v7
with:
fetch-depth: 0

Expand Down Expand Up @@ -79,7 +72,7 @@ jobs:
--output ${GITHUB_WORKSPACE}/build/coverage_report.xml

- name: Submit coverage build
uses: codecov/codecov-action@v6.0.0
uses: codecov/codecov-action@v7.1.1
with:
disable_search: true
fail_ci_if_error: false
Expand Down
78 changes: 38 additions & 40 deletions .github/workflows/ci_documentation.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
# SPDX-FileCopyrightText: 2006-2025 Knut Reinert & Freie Universität Berlin
# SPDX-FileCopyrightText: 2016-2025 Knut Reinert & MPI für molekulare Genetik
# SPDX-FileCopyrightText: 2006-2026 Knut Reinert & Freie Universität Berlin
# SPDX-FileCopyrightText: 2016-2026 Knut Reinert & MPI für molekulare Genetik
# SPDX-License-Identifier: CC0-1.0

# Builds and tests the documentation. PRs: upload the HTML; docs_preview.yml publishes it from the default branch.
# Push to main and hibf: deploy to docs.seqan.de from a separate job, so the server key never shares a job with
# CMake/Doxygen. Stays a separate workflow (not a CI stage) so that the preview appears as soon as this finishes.

name: Documentation

on:
push:
branches:
- 'main'
- 'hibf'
pull_request_target:
types:
- unlabeled
- closed
pull_request:
workflow_dispatch:

concurrency:
group: documentation-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name != 'push' }}

permissions:
contents: read

env:
SHARG_NO_VERSION_CHECK: 1
TZ: Europe/Berlin
Expand All @@ -31,18 +35,12 @@ jobs:
build:
name: Documentation
runs-on: ubuntu-latest
if: ( github.repository_owner == 'seqan' || github.event_name == 'workflow_dispatch' || github.event.label.name == 'lint' ) && github.event.action != 'closed'
if: github.repository_owner == 'seqan' || github.event_name == 'workflow_dispatch'
steps:
- name: Checkout
if: github.event_name != 'pull_request_target'
uses: actions/checkout@v6

# pull_request_target does not checkout the merge commit by default
- name: Checkout
if: github.event_name == 'pull_request_target'
uses: actions/checkout@v6
uses: actions/checkout@v7 # locked via actions.lock
with:
ref: "refs/pull/${{ github.event.number }}/merge"
persist-credentials: false

- name: Install Doxygen
uses: seqan/actions/setup-doxygen@main
Expand All @@ -60,35 +58,35 @@ jobs:
working-directory: build
run: make doc

- name: Deploy Preview
if: github.event_name == 'pull_request_target'
uses: seqan/actions/documentation_deploy_preview@main
# For docs_preview.yml (PRs) and the deploy job below. docs_preview.yml expects these artifact names.
- name: Upload documentation
uses: actions/upload-artifact@v7 # locked via actions.lock
with:
deploy_host: ${{ secrets.DEPLOY_HOST }}
deploy_user: ${{ secrets.DEPLOY_USER }}
deploy_ssh_key: ${{ secrets.DEPLOY_SSH_KEY }}
deploy_base_path: ${{ secrets.DEPLOY_PREVIEW_BASE_PATH }}
source_path_user_doc: build/html
token: ${{ secrets.SEQAN_ACTIONS_PAT }}
name: documentation
path: build/html/
retention-days: 7
if-no-files-found: error

- name: Deploy Documentation
if: github.event_name == 'push'
uses: seqan/actions/documentation_deploy_production@main
deploy:
name: Deploy Documentation
needs: build
if: github.repository_owner == 'seqan' && github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/hibf')
runs-on: ubuntu-latest
environment: server-deploy # deployment branches: main, hibf; holds the server key
steps:
- name: Download documentation
uses: actions/download-artifact@v8 # locked via actions.lock
with:
deploy_host: ${{ secrets.DEPLOY_HOST }}
deploy_user: ${{ secrets.DEPLOY_USER }}
deploy_ssh_key: ${{ secrets.DEPLOY_SSH_KEY }}
source_path_user_doc: build/html/
deploy_path_user_doc: ${{ secrets.DEPLOY_PRODUCTION_BASE_PATH }}/${{ github.ref_name}}
delete:
name: Delete Preview
runs-on: ubuntu-latest
if: github.repository_owner == 'seqan' && github.event_name == 'pull_request_target' && github.event.action == 'closed'
steps:
- name: Delete Preview
uses: seqan/actions/documentation_delete_preview@main
name: documentation
path: html

# Plain rsync with a pinned host key (no third-party deploy action): the key grants the whole server.
# Same targets as before.
- name: Deploy
uses: seqan/actions/documentation_deploy_production@main
with:
deploy_host: ${{ secrets.DEPLOY_HOST }}
deploy_user: ${{ secrets.DEPLOY_USER }}
deploy_ssh_key: ${{ secrets.DEPLOY_SSH_KEY }}
deploy_base_path: ${{ secrets.DEPLOY_PREVIEW_BASE_PATH }}
source_path_user_doc: html/
deploy_path_user_doc: ${{ secrets.DEPLOY_PRODUCTION_BASE_PATH }}/${{ github.ref_name }}
16 changes: 3 additions & 13 deletions .github/workflows/ci_install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,9 @@
name: Install

on:
push:
branches:
- 'main'
- 'hibf'
pull_request:
types:
- unlabeled
workflow_call:
workflow_dispatch:

concurrency:
group: install-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name != 'push' }}

env:
SHARG_NO_VERSION_CHECK: 1
TZ: Europe/Berlin
Expand All @@ -30,7 +20,7 @@ jobs:
build:
runs-on: ubuntu-latest
name: ${{ matrix.compiler }}
if: github.repository_owner == 'seqan' || github.event_name == 'workflow_dispatch' || github.event.label.name == 'lint'
if: github.repository_owner == 'seqan' || github.event_name == 'workflow_dispatch'
strategy:
fail-fast: false
matrix:
Expand All @@ -40,7 +30,7 @@ jobs:
options: --privileged
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v7
with:
path: needle

Expand Down
16 changes: 3 additions & 13 deletions .github/workflows/ci_license.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,20 @@
name: License

on:
push:
branches:
- 'main'
- 'hibf'
pull_request:
types:
- unlabeled
workflow_call:
workflow_dispatch:

concurrency:
group: license-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name != 'push' }}

env:
TZ: Europe/Berlin

jobs:
check:
name: REUSE Compliance
runs-on: ubuntu-latest
if: github.repository_owner == 'seqan' || github.event_name == 'workflow_dispatch' || github.event.label.name == 'lint'
if: github.repository_owner == 'seqan' || github.event_name == 'workflow_dispatch'
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: REUSE Compliance Check
uses: fsfe/reuse-action@v6
Loading
Loading