Utility Components

Utility components provide optional workflow enhancements for RADIUSS Shared CI pipelines. They aim at adding features that are not provided by GitLab.

Overview

RADIUSS Shared CI provides 3 utility components:

Component

Purpose

utility-draft-pr-filter

Skip CI on draft pull requests to save resources

utility-branch-skip

Skip CI on branches not associated with a PR

utility-job-override-check

Warn when updated shared spack-config jobs may conflict with local overrides

All components are optional and can be used independently or together.

utility-draft-pr-filter

Skip CI execution when a GitHub pull request is in draft state, saving machine time and resources until the PR is ready for review.

Purpose

  • Resource Conservation: Avoid running CI on work-in-progress PRs

  • Clear Communication: Explicitly marks draft PRs as “skipped” on GitHub

  • Flexible Override: Allow specific branches to always run (e.g., main, develop)

When to Use

Enable this utility when:

  • Your team uses GitHub draft PRs for work-in-progress

  • You want to reduce CI load on incomplete work

  • You have limited CI resources/allocations

Skip if:

  • Your team doesn’t use draft PRs

  • You want CI to run on all commits regardless of state

Inputs

Input

Required

Description

github_token

Yes

GitHub token with repo:status permission

github_project_name

Yes

GitHub repository name

github_project_org

Yes

GitHub organization name

always_run_pattern

No

Regex pattern for branches that always run (default: "^(main|master|develop)$")

Behavior

The component:

  1. Checks if current commit is from a GitHub PR

  2. If yes, queries GitHub API to check if PR is draft

  3. If draft: - Reports “Draft PR - CI skipped” to GitHub - Exits pipeline gracefully

  4. If not draft or branch matches always_run_pattern: - Pipeline continues normally

Usage

include:
  # Add after base-pipeline
  - component: $CI_SERVER_FQDN/radiuss/radiuss-shared-ci/base-pipeline@v2026.02.2
    inputs: { ... }

  - component: $CI_SERVER_FQDN/radiuss/radiuss-shared-ci/utility-draft-pr-filter@v2026.02.2
    inputs:
      github_token: $GITHUB_STATUS_TOKEN
      github_project_name: $GITHUB_PROJECT_NAME
      github_project_org: $GITHUB_PROJECT_ORG

Default behavior skips draft PRs except on main, master, or develop.

Custom Override Pattern

Customize which branches always run:

- component: .../utility-draft-pr-filter@v2026.02.2
  inputs:
    github_token: $GITHUB_STATUS_TOKEN
    github_project_name: $GITHUB_PROJECT_NAME
    github_project_org: $GITHUB_PROJECT_ORG
    always_run_pattern: "^(main|develop|release/.*)$"

This allows:

  • main - Always runs

  • develop - Always runs

  • release/v1.0 - Always runs

  • feature/draft-pr - Skips if draft

Examples

Basic Setup

# .gitlab-ci.yml
include:
  - component: .../base-pipeline@v2026.02.2
    inputs:
      github_project_name: "my-project"
      github_project_org: "LLNL"
      github_token: $GITHUB_STATUS_TOKEN

  # Add draft PR filter
  - component: .../utility-draft-pr-filter@v2026.02.2
    inputs:
      github_token: $GITHUB_STATUS_TOKEN
      github_project_name: "my-project"
      github_project_org: "LLNL"

No Override (Run on All Branches)

To always run CI regardless of draft status:

- component: .../utility-draft-pr-filter@v2026.02.2
  inputs:
    github_token: $GITHUB_STATUS_TOKEN
    github_project_name: "my-project"
    github_project_org: "LLNL"
    always_run_pattern: ".*"  # Match all branches

This effectively disables the filter while keeping it in configuration.

utility-branch-skip

Skip CI execution on branches that are not associated with an open GitHub pull request, reducing noise from experimental or personal branches.

Purpose

  • Reduce CI Noise: Avoid running CI on experimental branches

  • Save Resources: Only run CI on branches being reviewed

  • PR-Focused Workflow: Enforce “no CI without PR” policy

When to Use

Enable this utility when:

  • You want CI only on pull requests

  • You have many feature/experimental branches

  • You want to reduce unnecessary CI runs

Skip if:

  • You want CI on all branch pushes

  • Your main/develop branches need CI without PRs

  • Your workflow doesn’t center around PRs

Warning

This utility will skip CI on your main/develop branches unless you:

  1. Use always_run_pattern to override (recommended), OR

  2. Always have PRs open for those branches

Inputs

Input

Required

Description

github_token

Yes

GitHub token with repo:status permission

github_project_name

Yes

GitHub repository name

github_project_org

Yes

GitHub organization name

always_run_pattern

No

Regex pattern for branches that always run (default: "^(main|master|develop)$")

Behavior

The component:

  1. Checks if current branch has an open PR on GitHub

  2. If no PR found: - Checks if branch matches always_run_pattern - If no match: Reports “Not a PR - CI skipped” and exits - If match: Pipeline continues

  3. If PR found: - Pipeline continues normally

Usage

include:
  - component: .../base-pipeline@v2026.02.2
    inputs: { ... }

  - component: .../utility-branch-skip@v2026.02.2
    inputs:
      github_token: $GITHUB_STATUS_TOKEN
      github_project_name: $GITHUB_PROJECT_NAME
      github_project_org: $GITHUB_PROJECT_ORG

Default behavior runs CI on:

  • Any branch with an open PR

  • main, master, or develop (even without PR)

Custom Override Pattern

Customize which branches always run:

- component: .../utility-branch-skip@v2026.02.2
  inputs:
    github_token: $GITHUB_STATUS_TOKEN
    github_project_name: $GITHUB_PROJECT_NAME
    github_project_org: $GITHUB_PROJECT_ORG
    always_run_pattern: "^(main|develop|release/.*|hotfix/.*)$"

Examples

Basic Setup

include:
  - component: .../base-pipeline@v2026.02.2
    inputs: { ... }

  # Skip branches without PRs
  - component: .../utility-branch-skip@v2026.02.2
    inputs:
      github_token: $GITHUB_STATUS_TOKEN
      github_project_name: "my-project"
      github_project_org: "LLNL"

Strict PR-Only Mode

Require PR for all branches (even main/develop):

- component: .../utility-branch-skip@v2026.02.2
  inputs:
    github_token: $GITHUB_STATUS_TOKEN
    github_project_name: "my-project"
    github_project_org: "LLNL"
    always_run_pattern: "^$"  # Empty pattern = no exceptions

Warning

This will skip CI on main/develop if they don’t have open PRs!

utility-job-override-check

Warn when shared CI job definitions in the radiuss-spack-configs submodule have changed in a way that may affect a project’s local job overrides, so developers can update their overrides before they silently drift out of sync.

Purpose

  • Catch Drift Early: Surface renamed, removed, or modified shared CI jobs that a branch’s submodule bump pulls in

  • Protect Local Overrides: Flag exactly which local overrides may need updating

  • Non-Blocking: Emits warnings only; the pipeline always continues

When to Use

Enable this utility when:

  • Your project pins radiuss-spack-configs as a submodule and leverages shared CI jobs

  • You maintain local job overrides that extend or replace shared CI jobs

  • You want a heads-up when a submodule bump changes the jobs you override

Skip if:

  • Your project does not vendor radiuss-spack-configs as a submodule

  • You use radiuss-spack-configs only for its Spack configs and define your own CI jobs locally (there are no shared CI jobs to override)

Inputs

All inputs are optional; defaults match the conventional RADIUSS project layout.

Input

Required

Description

submodule_path

No

Path to the radiuss-spack-configs submodule (default: "scripts/radiuss-spack-configs")

shared_jobs_path

No

Path to shared job definitions within the submodule (default: "gitlab/radiuss-jobs")

local_jobs_path

No

Path to local job overrides in the project (default: ".gitlab/jobs")

machine_files

No

Space-separated list of machine YAML files to check (default: "dane.yml matrix.yml corona.yml tioga.yml tuolumne.yml")

ref_branch

No

Base branch used to detect divergence (default: "develop")

Behavior

The component runs only when the branch itself changed the submodule pointer (its rules compare the submodule path against ref_branch using the merge base). When it runs, it:

  1. Resolves the submodule commit at three points: the merge base with ref_branch (where the branch diverged), the branch HEAD, and ref_branch

  2. For each machine_files entry that has a matching local override, diffs the shared jobs between the merge-base commit and HEAD and reports:

    • Renamed/removed jobs that the project overrides locally

    • Modified jobs whose SPEC changed between the two commits

  3. Warns separately if ref_branch has also advanced the submodule, suggesting a merge to pick up the latest shared definitions

The check is advisory: the job uses allow_failure: true and never fails the pipeline.

Usage

include:
  - component: .../base-pipeline@v2026.02.2
    inputs: { ... }

  - component: $CI_SERVER_FQDN/radiuss/radiuss-shared-ci/utility-job-override-check@2026.6.0

With the conventional project layout no inputs are required. Override the defaults only when your paths differ:

- component: $CI_SERVER_FQDN/radiuss/radiuss-shared-ci/utility-job-override-check@2026.6.0
  inputs:
    submodule_path: "scripts/radiuss-spack-configs"
    shared_jobs_path: "gitlab/radiuss-jobs"
    local_jobs_path: ".gitlab/jobs"
    machine_files: "dane.yml matrix.yml corona.yml tioga.yml tuolumne.yml"
    ref_branch: "develop"

Combining Utilities

Both utilities can be used together for fine-grained control:

include:
  - component: .../base-pipeline@v2026.02.2
    inputs: { ... }

  # Skip draft PRs
  - component: .../utility-draft-pr-filter@v2026.02.2
    inputs:
      github_token: $GITHUB_STATUS_TOKEN
      github_project_name: $GITHUB_PROJECT_NAME
      github_project_org: $GITHUB_PROJECT_ORG

  # Skip non-PR branches
  - component: .../utility-branch-skip@v2026.02.2
    inputs:
      github_token: $GITHUB_STATUS_TOKEN
      github_project_name: $GITHUB_PROJECT_NAME
      github_project_org: $GITHUB_PROJECT_ORG

This configuration:

  • Skips CI on draft PRs (but runs when converted to ready)

  • Skips CI on branches without PRs

  • Always runs CI on main/master/develop (even without PR)

  • Runs CI on non-draft PRs for any branch

Common Issues

Token Missing or Invalid

Error: “GitHub API request failed” or “remote: Permission to LLNL/my-project.git denied”

Solutions:

  1. Verify GITHUB_STATUS_TOKEN is set in GitLab UI (CI/CD variables)

  2. Check token hasn’t expired (regenerate if needed)

  3. Ensure token has repo:status permission minimum

Note

Token must have a maximum of 30 days validity to comply with LLNL’s security policies.

CI Skipped on Main Branch

Symptom: Main branch shows “Not a PR - CI skipped”

Solution: Verify always_run_pattern includes your main branch:

inputs:
  always_run_pattern: "^(main|master|develop)$"

Check your branch name matches (e.g., “main” vs “master”).

CI Runs on Draft PRs

Symptom: Draft PRs still trigger full CI

Possible causes:

  1. Component not included: Verify draft-pr-filter is in .gitlab-ci.yml

  2. Token missing: Check github_token input provided

  3. Branch override: Branch matches always_run_pattern

Regex Pattern Not Matching

Symptom: Branch you expected to run gets skipped

Solution: Test your regex pattern. Common mistakes:

# Wrong: Matches branches containing these words anywhere
always_run_pattern: "main|develop"

# Right: Matches branches that are exactly these names
always_run_pattern: "^(main|develop)$"

# Right: Matches branches starting with "release/"
always_run_pattern: "^(main|develop|release/.*)"

See Also

  • base-pipeline - Core orchestration component

  • ../getting_started/choosing-your-path - Choosing utilities guide

  • ../user_guide/quick-reference - Quick utility setup reference

Related Topics:

  • GitHub token permissions and scopes

  • GitLab CI rules and workflow control

  • Draft PR workflows