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
2 changes: 1 addition & 1 deletion .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ ubuntu-22.04, macos-13, macos-14, windows-2022 ]
os: [ ubuntu-22.04, macos-14, windows-2022 ]
defaults:
run:
shell: bash -l {0}
Expand Down
18 changes: 12 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, macos-13, macos-14, windows-2022]
os: [ubuntu-22.04, macos-14, windows-2022]
defaults:
run:
shell: bash

steps:
- name: Checkout repo
uses: actions/checkout@v5

- name: Checkout modflow6
uses: actions/checkout@v5
with:
Expand Down Expand Up @@ -88,19 +91,22 @@ jobs:
# - name: Setup tmate session
# uses: mxschmitt/action-tmate@v3

- name: Fetch pre-built programs
run: |
ostag="${{ steps.ostag.outputs.ostag }}"
mkdir $ostag
python3 scripts/fetch_releases.py --manifest releases.json --ostag $ostag --outdir $ostag --zip $ostag.zip

- name: Build programs
uses: nick-fields/retry@v3
with:
shell: bash
timeout_minutes: 40
command: |
ostag="${{ steps.ostag.outputs.ostag }}"
mkdir $ostag
pixi run --manifest-path modflow6/pixi.toml make-program : --appdir $ostag --exclude gridgen --zip $ostag.zip --verbose
fetched=$(python3 scripts/fetch_releases.py --manifest releases.json --list)
pixi run --manifest-path modflow6/pixi.toml make-program : --appdir $ostag --exclude "$fetched" --zip $ostag.zip --verbose
pixi run --manifest-path modflow6/pixi.toml make-program mf2005,mflgr,mfnwt,mfusg --appdir $ostag --double --keep --zip $ostag.zip --verbose
if [[ "${{ matrix.os }}" == "macos-14" ]]; then
pixi run --manifest-path modflow6/pixi.toml make-program mf6 --appdir $ostag --keep --zip $ostag.zip --verbose --fflags='-O1'
fi
pixi run --manifest-path modflow6/pixi.toml make-code-json --appdir $ostag --zip $ostag.zip --verbose

- name: Show programs
Expand Down
98 changes: 97 additions & 1 deletion DEVELOPER.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ This document provides guidance for using this repository to release USGS execut
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Overview](#overview)
- [Program sources](#program-sources)
- [Hybrid release system](#hybrid-release-system)
- [How it works](#how-it-works)
- [Adding a program](#adding-a-program)
- [Updating a version](#updating-a-version)
- [Future migration](#future-migration)
- [Triggering a release](#triggering-a-release)
- [GitHub UI](#github-ui)
- [GitHub CLI](#github-cli)
Expand Down Expand Up @@ -35,6 +41,96 @@ If the triggering event is `workflow_dispatch`:

**Note**: version numbers don't currently follow semantic versioning conventions, but simply increment an integer for each release.

## Program sources

The distribution includes programs from across the MODFLOW ecosystem. Each program's source code and/or pre-built binaries come from one of three places: a MODFLOW-ORG GitHub repository with platform binaries, a MODFLOW-ORG repository with source-only releases, or a USGS server. This table tracks the current state as of January 2026.

### Fetched from pre-built GitHub releases

These programs are downloaded as pre-built binaries via `releases.json`. Their repositories publish platform-specific archives (linux.zip, mac.zip, macarm.zip, win64.zip) as release assets.

| Program(s) | Repository | Release tag | Notes |
|------------|-----------|-------------|-------|
| mf6, zbud6, libmf6 | [MODFLOW-ORG/modflow6](https://github.com/MODFLOW-ORG/modflow6) | 6.6.3 | Assets named `mf6.6.3_{platform}.zip`, binaries nested in `bin/` subdirectory |
| triangle | [MODFLOW-ORG/triangle](https://github.com/MODFLOW-ORG/triangle) | v1.6 | |
| gridgen | [MODFLOW-ORG/gridgen](https://github.com/MODFLOW-ORG/gridgen) | v1.0.02 | |
| zonbud | [MODFLOW-ORG/zonbud](https://github.com/MODFLOW-ORG/zonbud) | v3.01 | |
| zonbudusg | [MODFLOW-ORG/zonbudusg](https://github.com/MODFLOW-ORG/zonbudusg) | v1.01 | |
| mfusg_gsi | [MODFLOW-ORG/mfusgt](https://github.com/MODFLOW-ORG/mfusgt) | v2.6.0 | Archive contains `mfusgt`, renamed to `mfusg_gsi` |

### Built from source by pymake

These programs are compiled by pymake because their repositories do not yet publish pre-built platform binaries.

| Program(s) | Source | Notes |
|------------|--------|-------|
| mf2005, mf2005dbl | [MODFLOW-ORG/mf2005](https://github.com/MODFLOW-ORG/mf2005) | Source-only release (v.1.12.00) |
| mfusg, mfusgdbl | [MODFLOW-ORG/mfusg](https://github.com/MODFLOW-ORG/mfusg) | Source-only release (v1.5.00) |
| mt3dms | [MODFLOW-ORG/mt3dms](https://github.com/MODFLOW-ORG/mt3dms) | Source-only release (2.0) |
| mt3dusgs | [MODFLOW-ORG/mt3d-usgs](https://github.com/MODFLOW-ORG/mt3d-usgs) | Source-only release (1.1.0) |
| mflgr, mflgrdbl | [USGS](https://water.usgs.gov/ogw/modflow-lgr/) | No GitHub repo |
| mfnwt, mfnwtdbl | [USGS](https://water.usgs.gov/water-resources/software/MODFLOW-NWT/) | No GitHub repo |
| mp6 | [USGS](https://water.usgs.gov/water-resources/software/MODPATH/) | No GitHub repo |
| mp7 | [USGS](https://water.usgs.gov/water-resources/software/MODPATH/) | [MODFLOW-ORG/modpath-v7](https://github.com/MODFLOW-ORG/modpath-v7) exists but has no releases |
| crt | [USGS](https://water.usgs.gov/ogw/CRT/) | No GitHub repo |
| vs2dt | [USGS](https://water.usgs.gov/water-resources/software/VS2DI/) | No GitHub repo |
| sutra | [USGS](https://water.usgs.gov/water-resources/software/sutra/) | No GitHub repo |
| mf2000 | [USGS](https://water.usgs.gov/nrp/gwsoftware/modflow2000/) | No GitHub repo |
| swtv4 | [USGS](https://water.usgs.gov/water-resources/software/SEAWAT/) | No GitHub repo |

To move a program from "built by pymake" to "fetched from releases", its repository needs to start publishing platform-specific binary archives as GitHub release assets, then an entry can be added to `releases.json` (see [Adding a program](#adding-a-program)).

## Hybrid release system

The release workflow uses a hybrid approach: some programs are downloaded as pre-built binaries from their independently managed GitHub repositories, while others are still compiled from source by pymake. This is a stopgap until the [modflow-devtools programs API](https://github.com/MODFLOW-ORG/modflow-devtools/issues/263) is ready to manage all program installations.

### How it works

The file `releases.json` in the repository root is a manifest listing programs to fetch from GitHub releases. Each entry specifies a source repository, release tag, platform-specific asset filenames, and a mapping of output program names to archive filenames.

During a release build, the workflow:

1. Runs `scripts/fetch_releases.py` to download pre-built binaries for the current platform from each repository listed in `releases.json`.
2. Runs pymake to compile the remaining programs, excluding those already fetched.
3. Combines everything into the platform zip alongside pymake-generated metadata.

The fetch script handles platform-specific file extensions (`.exe`, `.dll`, `.dylib`, `.so`) and supports renaming programs when the archive filename differs from the distribution name (e.g., `mfusgt` in the archive becomes `mfusg_gsi` in the distribution).

### Adding a program

When a program repository begins publishing pre-built platform binaries as release assets, add an entry to `releases.json`:

```json
{
"repo": "MODFLOW-ORG/<repo>",
"tag": "<release-tag>",
"assets": {
"linux": "linux.zip",
"mac": "mac.zip",
"macarm": "macarm.zip",
"win64": "win64.zip"
},
"programs": {
"<output-name>": "<archive-name>"
}
}
```

- `repo`: GitHub owner/name
- `tag`: release tag to download from
- `assets`: platform-to-asset-filename mapping (must match the release asset names)
- `programs`: maps the desired output filename to the filename inside the archive. If they are the same, use the same value for both.

The program will automatically be excluded from the pymake build. No workflow changes are needed.

### Updating a version

To update a program to a new release, change the `tag` field in its `releases.json` entry (and update asset filenames if they changed). The next release build will fetch the new version.

### Future migration

This hybrid system will be replaced by the [modflow-devtools programs API](https://github.com/MODFLOW-ORG/modflow-devtools/issues/263) once it is ready. The programs API uses a similar model (repository + tag + platform assets) but adds registry synchronization, caching, and multi-version management. At that point, `releases.json` and `scripts/fetch_releases.py` can be removed and replaced with a `programs install` command. When installation of the full suite is possible with devtools it is possible a combined distribution like this repository becomes less of a necessity but it becomes trivially maintainable.

## Triggering a release

The `workflow_dispatch` event is GitHub's mechanism for manually triggering workflows. This can be accomplished from the Actions tab in the GitHub UI, or via the [GitHub CLI](https://cli.github.com/manual/gh_workflow_run).
Expand Down Expand Up @@ -63,4 +159,4 @@ gh workflow run <workflow>.yml -R MODFLOW-ORG/executables

```shell
gh workflow run <workflow>.yml -R MODFLOW-ORG/executables -r master
```
```
82 changes: 82 additions & 0 deletions releases.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
[
{
"repo": "MODFLOW-ORG/modflow6",
"tag": "6.6.3",
"assets": {
"linux": "mf6.6.3_linux.zip",
"mac": "mf6.6.3_mac.zip",
"macarm": "mf6.6.3_macarm.zip",
"win64": "mf6.6.3_win64.zip"
},
"programs": {
"mf6": "mf6",
"zbud6": "zbud6",
"libmf6": "libmf6"
}
},
{
"repo": "MODFLOW-ORG/triangle",
"tag": "v1.6",
"assets": {
"linux": "linux.zip",
"mac": "mac.zip",
"macarm": "macarm.zip",
"win64": "win64.zip"
},
"programs": {
"triangle": "triangle"
}
},
{
"repo": "MODFLOW-ORG/gridgen",
"tag": "v1.0.02",
"assets": {
"linux": "linux.zip",
"mac": "mac.zip",
"macarm": "macarm.zip",
"win64": "win64.zip"
},
"programs": {
"gridgen": "gridgen"
}
},
{
"repo": "MODFLOW-ORG/zonbud",
"tag": "v3.01",
"assets": {
"linux": "linux.zip",
"mac": "mac.zip",
"macarm": "macarm.zip",
"win64": "win64.zip"
},
"programs": {
"zonbud": "zonbud"
}
},
{
"repo": "MODFLOW-ORG/zonbudusg",
"tag": "v1.01",
"assets": {
"linux": "linux.zip",
"mac": "mac.zip",
"macarm": "macarm.zip",
"win64": "win64.zip"
},
"programs": {
"zonbudusg": "zonbudusg"
}
},
{
"repo": "MODFLOW-ORG/mfusgt",
"tag": "v2.6.0",
"assets": {
"linux": "linux.zip",
"mac": "mac.zip",
"macarm": "macarm.zip",
"win64": "win64.zip"
},
"programs": {
"mfusg_gsi": "mfusgt"
}
}
]
Loading