# Release orchestration and scripts layout

Implementation plan for automated product releases in **`a2c-workflow`**, using GitLab REST API polling (not `glab` subprocess parsing) per [ADR-0009](../docs/adr/0009-release-semantics-and-master-promotion.md) and [ADR-0010](../docs/adr/0010-testpypi-pypi-publishing-gated-by-release-state.md).

## Status

| Phase | State |
|-------|-------|
| `scripts/README.md` script index | Done |
| `gitlab_api.py`, `release_ci_gates.py` | Done |
| `verify_release_ready.py`, `tag_release.py` | Done |
| `publish_release.py` orchestrator | Done |
| `scripts/` subfolder migration | Planned |

## Goal

One maintainer or AI entrypoint runs the full release without manual pipeline watching:

```bash
python scripts/publish_release.py --align-develop
```

The script reports explicit ADR states and stops on failure:

| Step | ADR state |
|------|-----------|
| Green Development CI on `release/X.Y.Z` | `code_clean` |
| Tag pushed, Release CI running | `release_candidate` |
| TestPyPI publish + smoke green | `testpypi_validated` |
| PyPI publish + smoke green | `released` |
| FF-merge `master` (and optional `develop`) | integrated |

## Orchestrator steps (`publish_release.py`)

1. `prepare` — `git fetch`; checkout `master`; pull
2. `branch` — `git checkout -b release/X.Y.Z`
3. `bump` — `python scripts/bump_release.py --yes`
4. `push-branch` — `git push -u origin release/X.Y.Z`
5. `wait-development-ci` — `verify_release_ready.py --ref release/X.Y.Z --profile branch --wait`
6. `tag` — `tag_release.py --ref release/X.Y.Z` (branch CI already verified)
7. `wait-release-ci` — `verify_release_ready.py --ref vX.Y.Z --profile tag --wait`
8. `merge-master` — FF-merge release branch to `master` and push
9. `merge-develop` — optional (`--align-develop`): FF-merge `master` into `develop`

Use `--dry-run`, `--from-step`, and `--stop-after` for partial runs.

## CI gate definitions (`release_ci_gates.py`)

### Development CI (`release/X.Y.Z`)

- `pre-commit`
- `workflow-docs:contract`
- `test:pytest`
- `build:package`
- `build:a2c-cli-binary`
- `build:a2c-cli-binary-linux-arm64`
- `build:a2c-tui-binary`
- `build:a2c-tui-binary-linux-arm64`

### Release CI (`vX.Y.Z`)

- `release:verify`
- `package:build`
- `package:a2c-cli-binary`
- `package:a2c-cli-binary-linux-arm64`
- `package:a2c-tui-binary`
- `package:a2c-tui-binary-linux-arm64`
- `package:smoke`
- `publish:gitlab`
- `publish:testpypi`
- `package:smoke-testpypi`
- `publish:pypi`
- `package:smoke-pypi`

Update these tuples when `.gitlab-ci.yml` changes.

## GitLab API authentication

Priority order in `gitlab_api.api_headers()`:

1. `GITLAB_SYNC_TOKEN`
2. `CI_JOB_TOKEN` (in GitLab CI)
3. `GITLAB_TOKEN` or `PRIVATE_TOKEN` (local maintainer / AI)

`glab` remains useful for ad-hoc human debugging; automation uses REST API directly.

## Future `scripts/` layout

Migrate without breaking ADR/CI paths by keeping thin wrappers at old locations until a dedicated migration release.

```
scripts/
  README.md
  lib/
    gitlab_api.py
    release_version.py
    release_refs.py
    release_ci_gates.py
  release/
    publish_release.py
    bump_release.py
    verify_release_ready.py
    tag_release.py
    verify_release_version.py
    registry_publish.py
  build/
    build_packages.py
    build_a2c_cli_binary.py
    build_a2c_tui_binary.py
    a2c_cli_entry.py
    a2c_tui_entry.py
  dev/
    setup-dev.sh
    setup-dev.ps1
    fix-git-ssl.ps1
  maintenance/
    generate_tui_screenshots.py
    sync_task_fixture_json.py
    smoke_install_packages.py
    smoke-ollama-decompose.sh
    smoke-ollama-decompose.ps1
```

## Parity with `a2c-vscode-extension`

The extension already ships `gitlab_api.py`, `verify_release_ready.py`, and `tag_release.py`. Workflow adds:

- Tag-profile gates (ADR-0010 publish chain)
- `publish_release.py` top-level orchestrator with branch creation and `master`/`develop` promotion

Consider extracting shared `gitlab_api.py` into a small internal package later; duplicate modules are acceptable until a third consumer appears.

## Related

- [scripts/README.md](../docs/scripts/README.md)
- [docs/release-pipeline.md](../docs/release-pipeline.md)
- [docs/package-publishing.md](../docs/package-publishing.md)
