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
103 changes: 40 additions & 63 deletions .github/workflows/Breakage.yml
Original file line number Diff line number Diff line change
@@ -1,87 +1,64 @@
# Ref: https://securitylab.github.com/research/github-actions-preventing-pwn-requests
name: Breakage

# read-only repo token
# no access to secrets
# The packages that depend on OptimalControl (derived from the Project.toml files) and the
# tutorials, then the applications, tested against it; one report per group. On push to
# main and by hand, the run is the baseline the next release PR compares with (REL1); see
# CTActions docs/workflows/breakage-suite.md.

on:
pull_request:
types: [labeled, synchronize, reopened]
push:
branches: [main]
workflow_dispatch:

jobs:
break-pkg:
packages:
# A 'labeled' event fires once per label added, and re-evaluates against the PR's
# *current* full label set — so adding several labels in a row would otherwise
# re-run this job on every subsequent label add. Only react to 'labeled' when it's
# this specific label; for other trigger types (opened/synchronize/reopened), fall
# back to checking the current label set as before.
# this specific label; for other trigger types (synchronize/reopened), fall back to
# checking the current label set as before. On push to main and by hand, always.
if: >
github.event_name != 'pull_request' ||
(github.event.action == 'labeled' && github.event.label.name == 'run breakage') ||
(github.event.action != 'labeled' && contains(github.event.pull_request.labels.*.name, 'run breakage'))
strategy:
fail-fast: false
matrix:
pkgname:
- OptimalControlProblems
- Tutorials
pkgversion:
- latest
- stable
include:
- pkgbreak: test
- pkgbreak: doc
pkgname: Tutorials
- pkgpath: control-toolbox
uses: control-toolbox/CTActions/.github/workflows/breakage.yml@main
uses: control-toolbox/CTActions/.github/workflows/breakage-suite.yml@main
with:
pkgname: ${{ matrix.pkgname }}
pkgpath: ${{ matrix.pkgpath }}
pkgversion: ${{ matrix.pkgversion }}
pkgbreak: ${{ matrix.pkgbreak }}
group: packages
# the packages that load OptimalControl are derived; the tutorials build their docs
targets: >-
[{"name": "Tutorials", "break": "doc"}]
use_ct_registry: true
secrets:
SSH_KEY: ${{ secrets.SSH_KEY }}
break-pkg-app:
# See the comment on break-pkg above.

applications:
# The applications and tutorials, some of them owned outside control-toolbox.
# A 'labeled' event fires once per label added, and re-evaluates against the PR's
# *current* full label set — so adding several labels in a row would otherwise
# re-run this job on every subsequent label add. Only react to 'labeled' when it's
# this specific label; for other trigger types (synchronize/reopened), fall back to
# checking the current label set as before. On push to main and by hand, always.
if: >
github.event_name != 'pull_request' ||
(github.event.action == 'labeled' && github.event.label.name == 'run breakage applications') ||
(github.event.action != 'labeled' && contains(github.event.pull_request.labels.*.name, 'run breakage applications'))
strategy:
fail-fast: false
matrix:
pkgname:
- OptimalControlProblems
- Tutorials
- CalculusOfVariations
- LossControl
- GeometricPreconditioner
- MedicalResonanceImaging
- Kepler
- PWLdynamics
- SIRcontrol
- DiauxicGrowth
- CTMembraneFiltration
pkgversion:
- latest
- stable
include:
- pkgbreak: doc
- pkgbreak: test
pkgname: OptimalControlProblems
- pkgpath: control-toolbox
- pkgpath: agustinyabo
pkgname: PWLdynamics
- pkgpath: AnasXbouali
pkgname: SIRcontrol
- pkgpath: agustinyabo
pkgname: DiauxicGrowth
- pkgpath: remydutto
pkgname: CTMembraneFiltration
uses: control-toolbox/CTActions/.github/workflows/breakage.yml@main
uses: control-toolbox/CTActions/.github/workflows/breakage-suite.yml@main
with:
pkgname: ${{ matrix.pkgname }}
pkgpath: ${{ matrix.pkgpath }}
pkgversion: ${{ matrix.pkgversion }}
pkgbreak: ${{ matrix.pkgbreak }}
group: applications
consumers: false
targets: >-
[{"name": "OptimalControlProblems"}, {"name": "Tutorials", "break": "doc"},
{"name": "CalculusOfVariations", "break": "doc"},
{"name": "LossControl", "break": "doc"},
{"name": "GeometricPreconditioner", "break": "doc"},
{"name": "MedicalResonanceImaging", "break": "doc"},
{"name": "Kepler", "break": "doc"},
{"name": "PWLdynamics", "owner": "agustinyabo", "break": "doc"},
{"name": "SIRcontrol", "owner": "AnasXbouali", "break": "doc"},
{"name": "DiauxicGrowth", "owner": "agustinyabo", "break": "doc"},
{"name": "CTMembraneFiltration", "owner": "remydutto", "break": "doc"}]
use_ct_registry: true
secrets:
SSH_KEY: ${{ secrets.SSH_KEY }}
2 changes: 2 additions & 0 deletions .github/workflows/Documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on:
- 'v[0-9]+\.[0-9]+\.[0-9]+'
pull_request:
types: [labeled, synchronize, reopened]
# run on a tag by ReleaseTag.yml: a tag it creates triggers no push event
workflow_dispatch:

# A GPU-attempt job now runs behind every push/tag build (see `gpu_runner` below) and
# can take up to `gpu_timeout_minutes`. Without this, two pushes to `main` in quick
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/ReleaseGate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Release gate

# REL1-REL7 of ct-conventions on every PR (a PR that does not change the version passes at
# once); see CTActions docs/workflows/release-gate.md.

on:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled, edited]

jobs:
call:
uses: control-toolbox/CTActions/.github/workflows/release-gate.yml@main
18 changes: 18 additions & 0 deletions .github/workflows/ReleaseTag.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Release tag

# Tags the merge commit of a release PR, creates its GitHub release and runs the
# documentation on the tag; see CTActions docs/workflows/release-tag.md.

on:
push:
branches: [main]
paths: [Project.toml]
workflow_dispatch:

permissions:
contents: write
actions: write

jobs:
call:
uses: control-toolbox/CTActions/.github/workflows/release-tag.yml@main
18 changes: 14 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,18 @@ is not the pinned tag, (re)create it:

```bash
rm -rf .conventions
git -c advice.detachedHead=false clone --quiet --depth 1 --branch v0.5.2 https://github.com/control-toolbox/ct-conventions.git .conventions
git -c advice.detachedHead=false clone --quiet --depth 1 --branch v0.7.0 https://github.com/control-toolbox/ct-conventions.git .conventions
```

**Pinned version: ct-conventions v0.5.2.** Cite rules by identifier (`MOD3`, `TST1`), and
**Pinned version: ct-conventions v0.7.0.** Cite rules by identifier (`MOD3`, `TST1`), and
state the version you applied in plans and reports.

Read in this order:

| File | Content |
| --- | --- |
| [`rules/general.md`](.conventions/rules/general.md) | Rules that hold everywhere — **always read** |
| [`README.md`](.conventions/README.md) | Index of the rule files, one per area (`MOD`, `TYP`, `DIM`, `EXC`, `PERF`, `DOC`, `TST`, `SITE`, `CHG`) |
| [`README.md`](.conventions/README.md) | Index of the rule files, one per area (`MOD`, `TYP`, `DIM`, `EXC`, `PERF`, `DOC`, `TST`, `SITE`, `CHG`, `REL`) |
| [`method.md`](.conventions/method.md) | How to work: tests, coverage, docs build, output capture |
| [`plan-template.md`](.conventions/plan-template.md) | Template for a substantial piece of work |

Expand All @@ -72,4 +72,14 @@ trigger labels are described in
- **1-D is a scalar** — a one-dimensional state/control/variable is a `Number` (`DIM1`).
- **Plan before code** — a local agent proposes a plan ([`plan-template.md`](.conventions/plan-template.md)) and waits for confirmation before working on code. The process for remote agents is still to be defined.
- **Docstrings last** — written once the implementation is stable (`DOC1`–`DOC8`).
- **The human merges** — an agent never merges a pull request.
- **The human merges** — an agent never merges a pull request, except a release PR in `autonomous` mode, and then only with `release.jl merge` (see below).

---

## Recurring tasks

- **Release.** When asked, in any language, to prepare a release, follow
[`recipes/release.md`](https://github.com/control-toolbox/ct-agents/blob/main/recipes/release.md)
of ct-agents (rules `REL1`–`REL7`). Read it with
`gh api repos/control-toolbox/ct-agents/contents/recipes/release.md -H "Accept: application/vnd.github.raw"`.
Stable or beta is the human's choice: if the request does not say, ask; never infer it.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
`.conventions/`); `AGENTS.md` cites rules by identifier, `CLAUDE.md` redirects to it, and
the references to the former Handbook become rule identifiers. One `.markdownlint.json`
(`GEN2`) replaces the `markdownlint-disable MD024` comment of this changelog (`CHG2`).
- ct-conventions pinned at `v0.7.0` in `AGENTS.md`: the release rules `REL1`–`REL7` in the
index, and a *Recurring tasks* section pointing to the release recipe of ct-agents.

### 📚 Documentation

Expand All @@ -24,6 +26,13 @@ Versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

- **`init` and `initial_guess` together raise "Conflicting aliases" in descriptive mode too** ([#964](https://github.com/control-toolbox/OptimalControl.jl/issues/964)). Explicit mode already reported the conflict; descriptive mode, the common case, routed the leftover `init` to the strategies and rejected it as an unknown option, with unrelated suggestions. Both modes now run the same check before any routing.

### 🧪 Testing

- Release workflows: `ReleaseGate.yml` (the gate of a release PR, `REL1`–`REL7`) and
`ReleaseTag.yml` (tag and GitHub release of a merged release PR) call CTActions;
`Breakage.yml` moves to `breakage-suite.yml` (one report, the `REL1` check of a release
PR) and also runs on push to `main`; `Documentation.yml` accepts `workflow_dispatch`.

## [2.2.1-beta] — 2026-09-02

Documentation-infrastructure follow-up to the 2.2.0-beta site rewrite. No change to OptimalControl's API or runtime behaviour; nothing to migrate — see [BREAKING.md](BREAKING.md).
Expand Down
Loading