Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
9cf7a7a
Migrating from azure pipelines to GHA with minor updates for Ruff and…
lamkina Jan 19, 2026
1d0a80e
Fix strategy matrix for mypy workflow
anthony-ozdemir Feb 3, 2026
b3cfd71
Update .github/workflows/fprettify.yaml
lamkina Feb 4, 2026
8db7f40
Update .github/workflows/clang_format.yaml
lamkina Feb 4, 2026
88c8ce4
Removing reference to azure in root README
lamkina Feb 4, 2026
ec760cc
Removing pypi workflow
lamkina Feb 4, 2026
88e9fd6
Adding specific ruff workflow and removing old format and lint workflow
lamkina Feb 4, 2026
ff3a1e4
updating ruff yaml extension
lamkina Feb 4, 2026
34c5431
Fixing indentation
lamkina Feb 4, 2026
e484d0c
Updating ruff workflow to fix gha error
lamkina Feb 5, 2026
f280eb3
Testing ruff pwd
lamkina Feb 5, 2026
042b4eb
Fixing ruff directory issues
lamkina Feb 5, 2026
d98f177
Debugging ruff formatting path
lamkina Feb 5, 2026
ea96700
Trying to fix path issues with gha and ruff
lamkina Feb 5, 2026
5ac78f5
Fixing an argument bug
lamkina Feb 5, 2026
3f51459
Trying to fix build bug with paths
lamkina Feb 5, 2026
b6f5096
Making the branch name check a callable workflow
lamkina Feb 5, 2026
342d9dc
Fixing bug with branch workflow
lamkina Feb 5, 2026
c08da3d
Removing pylint
lamkina Feb 5, 2026
25b908f
Improving docstrings
lamkina Feb 5, 2026
5baa589
Changing all .yml to .yaml for consistency
lamkina Feb 10, 2026
e7fb61b
Adding docker login action instead of command
lamkina Feb 10, 2026
94e3293
Removing isort workflow and config in favor of ruff
lamkina Feb 11, 2026
f8a702e
Adding import sorting to the select
lamkina Feb 11, 2026
da811a1
Refactoring build script and adding intel, removing standalone mypy w…
lamkina Feb 11, 2026
b20cc71
Adding explicit tapenade version
lamkina Feb 11, 2026
80d874b
Updating readme for new workflow setup
lamkina Feb 11, 2026
4da3a78
Bumping clang format to version 20
lamkina Feb 11, 2026
053c384
Bumping actions checkout to v6
lamkina Feb 11, 2026
3f327d9
Removing MDO Lab codeowners
lamkina Feb 11, 2026
2ac4151
Removing import sorting by default from Ruff config and adding sortin…
lamkina Feb 11, 2026
05cfcee
Updating readme, refactoring build workflow, and adding mypy to build…
lamkina Feb 11, 2026
582951c
Minor update to the build workflow for turning intel/gcc on or off
lamkina Feb 11, 2026
7d7ef20
Fixing env bug
lamkina Feb 11, 2026
30a1c97
Improving the logic checks for the build workflow for intel/gcc
lamkina Feb 11, 2026
a2db2c1
Fixing mypy
lamkina Feb 11, 2026
08d7ff2
Creating composite actions for build workflow to split jobs
lamkina Feb 11, 2026
930109c
Fixing .yml to .yaml
lamkina Feb 11, 2026
502dadf
Adding a checkout step for composite actions workflow
lamkina Feb 11, 2026
8d0b709
Removing composite actions and trying yaml anchor approach
lamkina Feb 11, 2026
0a22772
Fixing yaml anchor
lamkina Feb 11, 2026
8b24add
Fixing yaml anchors pt 2
lamkina Feb 11, 2026
4adc7d8
Addressing new round of comments pt 1
lamkina Feb 13, 2026
b6571d6
Restoring fprettify shell script
lamkina Feb 13, 2026
8217298
Fixing secrets docs in readme
lamkina Feb 13, 2026
97e5837
Updating workflow options section
lamkina Feb 13, 2026
fd0814e
Readme update and accounting for local/global ruff toml configs
lamkina Feb 13, 2026
3286a73
Fixing ruff config again
lamkina Feb 13, 2026
f328a25
Adding a standalone mypy workflow
lamkina Feb 13, 2026
ddbaa7d
Updating readme with mypy workflow
lamkina Feb 13, 2026
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
File renamed without changes.
1 change: 0 additions & 1 deletion .github/CODEOWNERS

This file was deleted.

File renamed without changes.
File renamed without changes.
234 changes: 234 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
# GitHub Actions Workflows

Reusable GitHub Actions workflows for Supercritical repositories. These workflows are called from individual repositories using the `workflow_call` trigger.

## Available Workflows

| Workflow | Description |
| :------- | :---------- |
| `build.yaml` | Build and test code in Docker container |
| `tapenade.yaml` | Tapenade automatic differentiation checks |
| `clang_format.yaml` | C/C++ formatting checks |
| `fprettify.yaml` | Fortran 90 formatting checks |
| `ruff.yaml` | Python formatting and linting with Ruff |
| `mypy.yaml` | Python type checking with MyPy |
| `branch-name-check.yaml` | Enforce branch naming conventions |

---

## Workflow Options

Configuration inheritance/overrides are documented in each workflow section below.

### build.yaml

Docker-based build and test workflow using the `scritical/private-dev` image.
Runs GCC and/or Intel jobs based on `GCC` and `INTEL` input flags.

| Name | Type | Default | Description |
| :--- | :--- | :------ | :---------- |
| `TIMEOUT` | number | `120` | Runtime allowed for the job, in minutes |
| `GCC_CONFIG` | string | `""` | Path to GCC configuration file (from repository root) |
| `INTEL_CONFIG` | string | `""` | Path to Intel configuration file (from repository root) |
| `INTEL` | boolean | `false` | Whether to run Intel-specific build and test steps |
| `GCC` | boolean | `true` | Whether to run GCC-specific build and test steps |
| `BUILD_SCRIPT` | string | `.github/build_real.sh` | Path to build script. Empty string skips this step |
| `TEST_SCRIPT` | string | `.github/test_real.sh` | Path to test script. Empty string skips this step |
| `TEST` | boolean | `true` | Whether to run the test step |

**Required Secrets:**
| Name | Description |
| :--- | :---------- |
| `DOCKER_USER` | Docker registry username |
| `DOCKER_OAT` | Docker registry Organization Access Token |

If these secrets are configured at the organization level, callers can use `secrets: inherit` instead of listing each secret.

---

### ruff.yaml

Python formatting and linting using Ruff.
The workflow checks out the org-wide Ruff configuration from `scritical/.github` and uses it for format, lint, and isort checks.

| Name | Type | Default | Description |
| :--- | :--- | :------ | :---------- |
| `MCCABE` | boolean | `false` | Enable McCabe complexity check (pass/fail, max complexity = 10) |
| `ISORT` | boolean | `false` | Enable import sorting check (pass/fail) |

**Configuration Override:** Create a `ruff.toml` in your repo with:
```toml
extend = "~/.config/ruff/ruff.toml"

# Local overrides here
[lint]
ignore = ["N802"]
```

---

### mypy.yaml

Runs MyPy type checking in the GCC OpenMPI Docker image.

| Name | Type | Default | Description |
| :--- | :--- | :------ | :---------- |
| `TIMEOUT` | number | `30` | Runtime allowed for the job, in minutes |

**Required Secrets:**
| Name | Description |
| :--- | :---------- |
| `DOCKER_USER` | Docker registry username |
| `DOCKER_OAT` | Docker registry Organization Access Token |

If these secrets are configured at the organization level, callers can use `secrets: inherit` instead of listing each secret.

---

### tapenade.yaml

Run Tapenade automatic differentiation and check for uncommitted changes.

| Name | Type | Default | Description |
| :--- | :--- | :------ | :---------- |
| `TIMEOUT` | number | `10` | Runtime allowed for the job, in minutes |
| `TAPENADE_SCRIPT` | string | `.github/build_tapenade.sh` | Path to Tapenade build script |

Uses Tapenade version 3.16 from tapenade_3.16-v2-723-ge8da61555.tar. Using a different version will create a diff.

Here is the link to our tapenade version: https://gitlab.inria.fr/tapenade/tapenade/-/package_files/112870/download

---

### clang_format.yaml

C/C++ code formatting checks using clang-format.

| Name | Type | Default | Description |
| :--- | :--- | :------ | :---------- |
| `TIMEOUT` | number | `10` | Runtime allowed for the job, in minutes |

**Configuration Override:** Create a `.clang-format` file in your repo root.

---

### fprettify.yaml

Fortran 90 code formatting checks using fprettify.

| Name | Type | Default | Description |
| :--- | :--- | :------ | :---------- |
| `TIMEOUT` | number | `10` | Runtime allowed for the job, in minutes |

**Configuration Override:** Create a `.fprettify.rc` file in your repo root.

---

### branch-name-check.yaml

Enforces branch naming conventions for pull requests:

- For PRs targeting `main`, source branches must start with `feature-`, `bugfix-`, or `hotfix-`.
- For PRs targeting `client-*`, source branches must start with `feature-`, `bugfix-`, or `hotfix-`.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to allow main to be merged into client branches?


## Setting Up Workflows

### Step 1: Create Workflow File

Create `.github/workflows/ci.yaml` in your repository:

```yaml
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
build:
uses: scritical/.github/.github/workflows/build.yaml@main
with:
GCC_CONFIG: config/defaults/config.LINUX_GFORTRAN.mk # If necessary
secrets:
DOCKER_USER: ${{ secrets.DOCKER_USER }}
DOCKER_OAT: ${{ secrets.DOCKER_OAT }}

ruff:
uses: scritical/.github/.github/workflows/ruff.yaml@main

clang-format:
uses: scritical/.github/.github/workflows/clang_format.yaml@main

fprettify:
uses: scritical/.github/.github/workflows/fprettify.yaml@main
```

### Step 2: Write Build Script

Create `.github/build_real.sh` in your repository:

```bash
#!/bin/bash
set -e
cp $CONFIG_FILE config/config.mk
make
pip install .
```

### Step 3: Write Test Script

Create `.github/test_real.sh` in your repository:

```bash
#!/bin/bash
set -e
./input_files/get-input-files.sh
testflo -v . -n 1
```

### Step 4: Add Secrets

In your orginaization settings, add the required secrets:
- `DOCKER_USER` - Docker organization name
- `DOCKER_OAT` - Docker Organization Access Token for pulling private images

---

## Complex Builds

For repositories requiring both real and complex builds:

```yaml
jobs:
build-real:
uses: scritical/.github/.github/workflows/build.yaml@main
with:
GCC_CONFIG: config/defaults/config.LINUX_GFORTRAN.mk
BUILD_SCRIPT: .github/build_real.sh
TEST_SCRIPT: .github/test_real.sh
secrets:
DOCKER_USER: ${{ secrets.DOCKER_USER }}
DOCKER_OAT: ${{ secrets.DOCKER_OAT }}

build-complex:
uses: scritical/.github/.github/workflows/build.yaml@main
with:
GCC_CONFIG: config/defaults/config.LINUX_GFORTRAN.mk
BUILD_SCRIPT: .github/build_complex.sh
TEST_SCRIPT: .github/test_complex.sh
secrets:
DOCKER_USER: ${{ secrets.DOCKER_USER }}
DOCKER_OAT: ${{ secrets.DOCKER_OAT }}
```

---

## Adding Status Badge

Add a status badge to your README:

```markdown
![CI](https://github.com/scritical/REPO_NAME/actions/workflows/ci.yaml/badge.svg)
```
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
name: Branch Name Check

on:
pull_request:
types: [opened, synchronize, reopened, edited]
branches:
- main
- 'client-*'
workflow_call:

jobs:
check-branch-name:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- name: Check branch name for main
if: github.base_ref == 'main'
Expand Down
113 changes: 113 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
on:
workflow_call:
inputs:
TIMEOUT:
type: number
default: 120
description: "Timeout for the job in minutes"
GCC_CONFIG:
type: string
default: ""
description: "Path to GCC configuration file"
INTEL_CONFIG:
type: string
default: ""
description: "Path to Intel configuration file"
INTEL:
type: boolean
default: false
description: "Whether to run Intel-specific build and test steps (if false, runs GCC steps)"
GCC:
type: boolean
default: true
description: "Whether to run GCC-specific build and test steps (if false, runs Intel steps)"
BUILD_SCRIPT:
type: string
default: ".github/build_real.sh"
description: "Path to build script"
TEST_SCRIPT:
type: string
default: ".github/test_real.sh"
description: "Path to test script"
TEST:
type: boolean
default: true
description: "Whether to run the test step"
secrets:
DOCKER_USER:
required: true
description: "Docker registry username"
DOCKER_OAT:
required: true
description: "Docker registry Organization Access Token"

env:
SCRITICAL_HOMEDIR: /home/scriticaluser
BASHRC: /home/scriticaluser/.bashrc_scritical

jobs:
build-gcc:
if: inputs.GCC
runs-on: ubuntu-24.04
timeout-minutes: ${{ inputs.TIMEOUT }}
env:
DOCKER_TAG: u24-gcc-ompi-latest
CONFIG_FILE: ${{ inputs.GCC_CONFIG }}
steps: &build_steps
- name: Checkout repository
uses: actions/checkout@v6

- name: Set repo environment variables
run: |
repo_name="${{ github.event.repository.name }}"
echo "REPO_NAME=$repo_name" >> "$GITHUB_ENV"
echo "DOCKER_WORKING_DIR=${{ env.SCRITICAL_HOMEDIR }}/repos/$repo_name" >> "$GITHUB_ENV"
echo "DOCKER_MOUNT_DIR=${{ env.SCRITICAL_HOMEDIR }}/mount/$repo_name" >> "$GITHUB_ENV"

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_OAT }}

- name: Start Docker container
run: |
docker run -t -d --name app \
--mount "type=bind,src=${{ github.workspace }},target=${{ env.DOCKER_MOUNT_DIR }}" \
scritical/private-dev:${{ env.DOCKER_TAG }} /bin/bash

# Copy repo to working directory
docker exec app /bin/bash -c "rm -rf $DOCKER_WORKING_DIR && mkdir -p $DOCKER_WORKING_DIR && cp -a $DOCKER_MOUNT_DIR/. $DOCKER_WORKING_DIR/"

- name: Build
if: inputs.BUILD_SCRIPT != ''
run: |
docker exec \
-e CONFIG_FILE="${{ env.CONFIG_FILE }}" \
app /bin/bash -c ". $BASHRC && cd $DOCKER_WORKING_DIR && /bin/bash ${{ inputs.BUILD_SCRIPT }}"

- name: Test
if: inputs.TEST_SCRIPT != '' && inputs.TEST
run: |
docker exec \
-e AGENT_NAME="${{ runner.name }}" \
-e BUILD_REASON="${{ github.event_name }}" \
app /bin/bash -c ". $BASHRC && cd $DOCKER_WORKING_DIR && source ~/MPIOversubscribe.sh && /bin/bash ${{ inputs.TEST_SCRIPT }}"

- name: Cleanup
if: always()
run: |
# Stop and remove the container only if it exists to avoid noisy errors.
if docker ps -a --format '{{.Names}}' | grep -qx app; then
docker stop app && docker rm app || true
fi

build-intel:
if: inputs.INTEL
runs-on: ubuntu-24.04
timeout-minutes: ${{ inputs.TIMEOUT }}
env:
DOCKER_TAG: u24-intel-impi-latest
CONFIG_FILE: ${{ inputs.INTEL_CONFIG }}
steps: *build_steps

Loading