Overview
Phase 5 of the autolens_profiling z_feature roadmap — wire up GitHub Actions for the new repo. Two distinct workflows shipped in the same PR but kept in separate .yml files:
- Workflow 1 (PR + push to main) — cheap, fast (<5 min), CPU-only: ruff lint + format check, markdown link-rot check, smoke import / dry-run of one script per section.
- Workflow 2 (manual + on release tag) — re-run the real profile scripts, regenerate JSON+PNG artifacts under
results/, call scripts/build_readme.py from Phase 4 to refresh the tables, commit the diff back to main.
Depends on Phase 0 (repo exists, shipped) and benefits from Phase 4 ([issue to-be-created], dashboard build script). If Phase 4 hasn't shipped when Phase 5 runs, Workflow 2's "refresh README" step can stub to just committing the new JSONs; flip on once build_readme.py lands.
Plan
- Add
.github/workflows/lint.yml for the PR / push gate.
- Add
.github/workflows/profile.yml for the release / manual profile re-run + README refresh.
- Add
pyproject.toml with the ruff config copied from PyAutoLens/pyproject.toml for parity across PyAutoLabs repos.
- Add
.github/workflows/README.md documenting which workflow does what and how to trigger Workflow 2 manually.
- Wire
AUTOLENS_PROFILING_SMOKE=1 env var into every profile-able script so Workflow 1's smoke step short-circuits to a tiny problem size (no real result artifacts produced).
- Document the open design decisions (runner type, cadence, bot identity, failure handling) inline in the workflow YAML comments so future maintainers see the reasoning.
Detailed implementation plan
Affected Repositories
PyAutoLabs/autolens_profiling (primary, target).
PyAutoLabs/PyAutoLens (read-only reference — copy .github/workflows/ patterns + pyproject.toml ruff config).
Work Classification
CI / infrastructure (workspace-style — no Python library code changes). Manual worktree setup.
Branch Survey
| Repository |
Current Branch |
Dirty? |
./autolens_profiling |
main |
clean |
Suggested branch: feature/ci-actions
Worktree root: ~/Code/PyAutoLabs-wt/ci-actions/
Workflow 1 — lint.yml (PR + push to main)
Should run in <5 min on a GitHub-hosted ubuntu runner with no JAX install. Checks:
ruff check (Python lint).
ruff format --check (formatting parity with PyAutoLens / sister repos).
- Markdown link-rot via
lychee (cheap, runs offline-friendly).
- Smoke import / dry-run of:
- The smallest pixelization profile script (probably
likelihood/imaging/mge.py with AUTOLENS_PROFILING_SMOKE=1).
- The cheapest simulator (probably
simulators/imaging.py at default instrument with smoke flag).
- The smallest Nautilus run (
searches/nautilus/simple.py with n_live=10).
- The smoke step must not produce real artifacts — short-circuit to tiny problem size and skip the JSON+PNG write, or write to a temp dir that's discarded.
Workflow 2 — profile.yml (manual + release-triggered)
workflow_dispatch (manual) plus on: release: types: [published]. Steps:
- Install PyAutoLens + dependencies (full install, not smoke).
- Run each script under
likelihood/, simulators/, searches/ — capture stdout to logs, write JSON+PNG to results/.
- Run
python scripts/build_readme.py (from Phase 4) to refresh markdown tables across all READMEs.
- Commit the diff back to
main with author github-actions[bot] and [skip ci] in the subject to avoid loops.
- If any single profile script fails, mark that cell
ERR in the dashboard tables and continue (don't fail the whole workflow on one regression).
Files to produce
.github/workflows/lint.yml (Workflow 1).
.github/workflows/profile.yml (Workflow 2).
.github/workflows/README.md documenting both.
pyproject.toml carrying the ruff config (copy from PyAutoLens/pyproject.toml).
- Optional
.lychee.toml for markdown link-rot config if defaults aren't enough.
Open design decisions
- Runners: CPU-only on GitHub-hosted runners, or self-hosted GPU runners? Recommend: GitHub-hosted CPU-only first; structure Workflow 2 so a future self-hosted GPU job can append GPU numbers without touching the workflow shape. (HPC-GPU results would land manually for now via a
results/*_a100_v*.json upload from the user.)
- Cadence: every release? weekly cron? manual only? Recommend: manual + on release tag so we don't burn CI minutes on noise.
- Bot identity:
github-actions[bot] with [skip ci] in subject; needs contents: write permission on the workflow.
- Failure handling: continue-on-error per script + cell marked
ERR in the dashboard. Recommend this over "fail whole workflow on one regression".
- Smoke env var name:
AUTOLENS_PROFILING_SMOKE=1 (proposed). Open to a different name if there's a convention in sister repos worth following.
Implementation Steps
-
Set up worktree manually:
source admin_jammy/software/worktree.sh
worktree_create ci-actions autolens_profiling
cd ~/Code/PyAutoLabs-wt/ci-actions/autolens_profiling
git checkout -b feature/ci-actions
-
Copy pyproject.toml ruff config from PyAutoLens/pyproject.toml. Keep only the [tool.ruff] section — this repo isn't a Python package, so no [project] table.
-
Author .github/workflows/lint.yml (Workflow 1) modelled on PyAutoLens/.github/workflows/.
-
Thread AUTOLENS_PROFILING_SMOKE=1 through every profile script: short-circuit to tiny problem size (e.g. n_live=10 for Nautilus, smallest mask for imaging, single channel for datacube), skip JSON+PNG writes. Touch all 10+ profile scripts.
-
Author .github/workflows/profile.yml (Workflow 2). If Phase 4's scripts/build_readme.py exists, call it; if not, stub the README-refresh step with a TODO comment.
-
Author .github/workflows/README.md documenting both workflows.
-
Smoke locally by running act or gh workflow run against the lint workflow.
-
Open PR against main of PyAutoLabs/autolens_profiling. PR body: link this issue + summary of design choices made + which open decisions were resolved.
Key Files
- New:
.github/workflows/lint.yml, .github/workflows/profile.yml, .github/workflows/README.md.
- New:
pyproject.toml (or setup.cfg) for ruff config.
- Edit: every profile script (
likelihood/**/*.py, simulators/*.py, searches/nautilus/*.py) — add AUTOLENS_PROFILING_SMOKE short-circuit.
- Reference (read-only):
PyAutoLens/pyproject.toml, PyAutoLens/.github/workflows/*.yml.
F1 lesson applied
Workflow 2's profile-rerun step regenerates the JSON+PNG artifacts the dashboard reads. Make sure it copies the input datasets from this repo (not from _developer) so the CI run reflects what an end user sees. Phase 1's re-mirror (PR #3) ensures these are clean origin/main snapshots.
Out of scope
- Cross-platform matrix (macOS, Windows) — lens-modeling profiling is Linux-only in practice.
- PyPI / conda packaging — the repo isn't a Python package.
- Coverage reporting — there are no unit tests in this repo, by design.
- Self-hosted GPU runner provisioning — design Workflow 2 so it can be added later without restructuring.
Original Prompt
Click to expand starting prompt
The full prompt content is preserved at PyAutoPrompt/issued/ci_actions.md after this issue is created.
Overview
Phase 5 of the autolens_profiling z_feature roadmap — wire up GitHub Actions for the new repo. Two distinct workflows shipped in the same PR but kept in separate
.ymlfiles:results/, callscripts/build_readme.pyfrom Phase 4 to refresh the tables, commit the diff back tomain.Depends on Phase 0 (repo exists, shipped) and benefits from Phase 4 ([issue to-be-created], dashboard build script). If Phase 4 hasn't shipped when Phase 5 runs, Workflow 2's "refresh README" step can stub to just committing the new JSONs; flip on once
build_readme.pylands.Plan
.github/workflows/lint.ymlfor the PR / push gate..github/workflows/profile.ymlfor the release / manual profile re-run + README refresh.pyproject.tomlwith theruffconfig copied fromPyAutoLens/pyproject.tomlfor parity across PyAutoLabs repos..github/workflows/README.mddocumenting which workflow does what and how to trigger Workflow 2 manually.AUTOLENS_PROFILING_SMOKE=1env var into every profile-able script so Workflow 1's smoke step short-circuits to a tiny problem size (no real result artifacts produced).Detailed implementation plan
Affected Repositories
PyAutoLabs/autolens_profiling(primary, target).PyAutoLabs/PyAutoLens(read-only reference — copy.github/workflows/patterns +pyproject.tomlruff config).Work Classification
CI / infrastructure (workspace-style — no Python library code changes). Manual worktree setup.
Branch Survey
./autolens_profilingSuggested branch:
feature/ci-actionsWorktree root:
~/Code/PyAutoLabs-wt/ci-actions/Workflow 1 —
lint.yml(PR + push to main)Should run in <5 min on a GitHub-hosted ubuntu runner with no JAX install. Checks:
ruff check(Python lint).ruff format --check(formatting parity with PyAutoLens / sister repos).lychee(cheap, runs offline-friendly).likelihood/imaging/mge.pywithAUTOLENS_PROFILING_SMOKE=1).simulators/imaging.pyat default instrument with smoke flag).searches/nautilus/simple.pywithn_live=10).Workflow 2 —
profile.yml(manual + release-triggered)workflow_dispatch(manual) pluson: release: types: [published]. Steps:likelihood/,simulators/,searches/— capture stdout to logs, write JSON+PNG toresults/.python scripts/build_readme.py(from Phase 4) to refresh markdown tables across all READMEs.mainwith authorgithub-actions[bot]and[skip ci]in the subject to avoid loops.ERRin the dashboard tables and continue (don't fail the whole workflow on one regression).Files to produce
.github/workflows/lint.yml(Workflow 1)..github/workflows/profile.yml(Workflow 2)..github/workflows/README.mddocumenting both.pyproject.tomlcarrying theruffconfig (copy fromPyAutoLens/pyproject.toml)..lychee.tomlfor markdown link-rot config if defaults aren't enough.Open design decisions
results/*_a100_v*.jsonupload from the user.)github-actions[bot]with[skip ci]in subject; needscontents: writepermission on the workflow.ERRin the dashboard. Recommend this over "fail whole workflow on one regression".AUTOLENS_PROFILING_SMOKE=1(proposed). Open to a different name if there's a convention in sister repos worth following.Implementation Steps
Set up worktree manually:
Copy
pyproject.tomlruff config fromPyAutoLens/pyproject.toml. Keep only the[tool.ruff]section — this repo isn't a Python package, so no[project]table.Author
.github/workflows/lint.yml(Workflow 1) modelled onPyAutoLens/.github/workflows/.Thread
AUTOLENS_PROFILING_SMOKE=1through every profile script: short-circuit to tiny problem size (e.g.n_live=10for Nautilus, smallest mask for imaging, single channel for datacube), skip JSON+PNG writes. Touch all 10+ profile scripts.Author
.github/workflows/profile.yml(Workflow 2). If Phase 4'sscripts/build_readme.pyexists, call it; if not, stub the README-refresh step with a TODO comment.Author
.github/workflows/README.mddocumenting both workflows.Smoke locally by running
actorgh workflow runagainst the lint workflow.Open PR against
mainofPyAutoLabs/autolens_profiling. PR body: link this issue + summary of design choices made + which open decisions were resolved.Key Files
.github/workflows/lint.yml,.github/workflows/profile.yml,.github/workflows/README.md.pyproject.toml(orsetup.cfg) for ruff config.likelihood/**/*.py,simulators/*.py,searches/nautilus/*.py) — addAUTOLENS_PROFILING_SMOKEshort-circuit.PyAutoLens/pyproject.toml,PyAutoLens/.github/workflows/*.yml.F1 lesson applied
Workflow 2's profile-rerun step regenerates the JSON+PNG artifacts the dashboard reads. Make sure it copies the input datasets from this repo (not from
_developer) so the CI run reflects what an end user sees. Phase 1's re-mirror (PR #3) ensures these are clean origin/main snapshots.Out of scope
Original Prompt
Click to expand starting prompt
The full prompt content is preserved at
PyAutoPrompt/issued/ci_actions.mdafter this issue is created.