tools-cicd
share cicd scripts
Running tool locally
Example:
uv sync
AWS_PROFILE=dev-admin-terraform uv run cicd --help
uv run cicd --version # or `cicd version`
uv run pytest
Release Procedures
- This project uses "trunk" based development off of
master. - PRs are allowed but always folded back to
master. - Releasing is manual through the
publish.ymlworkflow. - To release:
- Ensure all your features are ready on
master - Trigger the
publish.ymlworkflow withworkflow_dispatchand choosepatch,minor, ormajorforbump.- The workflow runs
uv version --bumpto auto-rev the version, commitspyproject.toml+uv.lock, tagsvX.Y.Z, then builds withuv buildand publishes to PyPI.
- The workflow runs
- Ensure all your features are ready on
Multi-Repository Release Coordination
The quest-v2 project includes a coordinated release script that allows you to trigger deployments across all related Quest v2 repositories simultaneously, rather than having to manually trigger each repository's release workflow individually.
Prerequisites
-
GitHub CLI: Install the GitHub CLI tool
# macOS brew install gh # Ubuntu/Debian sudo apt install gh # Windows winget install GitHub.cli
-
Authentication: Authenticate with GitHub
gh auth login
-
Script Setup: Navigate to the quest-v2 directory and make the script executable
cd quest-v2 chmod +x release-all.sh
Usage
From the quest-v2 directory, the script supports promoting from develop to qa:
# Promote to QA
./release-all.sh
# Show help and options
./release-all.sh --help
What it does
The script will:
- Trigger the "Release" workflow on all three Quest v2 repositories:
allfly-quest-uiallfly-quest-core-apigds-api
- Promote code from
developbranch toqa - Provide real-time status updates and links to monitor progress
- Display a summary of successful and failed releases
Monitoring
After triggering the releases, you can monitor progress through:
- The provided GitHub Actions URLs in the script output
- GitHub's Actions tab in each repository
- Your configured Slack notifications (if enabled)
Note: The script requires appropriate permissions to trigger workflows on all three Quest v2 repositories. Ensure your GitHub account has the necessary access rights.
Vulnerability scans (cicd vscan)
Weekly dependency audit that also fixes what it can, as one PR per repo:
cicd vscan python # scan only (pip-audit against uv.lock)
cicd vscan python --fix --dry-run # show the upgrade plan, touch nothing
cicd vscan python --fix # upgrade uv.lock locally and re-scan
cicd vscan python --open-pr --notify # CI: commit, open/update `chore/vscan-python` PR, post to Slack
cicd vscan npm takes the same flags. It runs npm audit fix --package-lock-only (never --force) and
diffs package-lock.json to report what moved; fixes that need a breaking upgrade are listed under
"Needs attention". A dry run fixes and re-audits a throwaway copy, so its report matches a real run.
- Each vulnerable package is pinned to the smallest version that fixes all of its advisories
(
uv lock --upgrade-package pkg==x). Upgrades thatuvcan't resolve (e.g. another dependency caps the version) or that exceedmax_bumpare listed under "Needs attention" instead. - The PR branch is stable, so an unmerged PR is updated in place the next week instead of piling up.
- The PR must be pushed with
ACTIONS_PAT(notGITHUB_TOKEN) so PR checks run on it. - Per-repo overrides (display name, base branch,
max_bump, expiring ignores) live in.github/vscan.toml; seesrc/allfly/vscan/config.py. - Repos call the reusable workflow
.github/workflows/vscan.yml(usage at the top of that file). - Slack: posts when there are findings or the scan fails. Add
--notify-clean(ornotify_clean = trueinvscan.toml) to also post on clean runs. The reusable workflow posts its own alert if the job dies beforecicdcan report (e.g. checkout/token errors).
Ad-hoc notifications (cicd notify)
Post to Slack from any workflow step or laptop, without a purpose-built command. Needs SLACK_BOT_TOKEN,
and the bot must be invited to the target channel. --channel takes an ID or #name; pass env vars yourself
(e.g. --channel "$SLACK_RELEASES_CHANNEL").
# plain mrkdwn
cicd notify slack --channel "#releases" --text ":rocket: Desktop v1.4.0-dev.3 is out"
# card: header + body + fields + links + footer, no Block Kit needed
cicd notify slack --channel "$SLACK_RELEASES_CHANNEL" \
--title ":computer: Desktop app dev release" \
--text "New build available for internal testing" \
--field Version=1.4.0-dev.3 --field Platform=macOS \
--link "https://example.com/download|Download" --link "https://example.com/notes|Release notes" \
--context "Triggered by $GITHUB_ACTOR"
# full Block Kit (inline JSON, @file, or - for stdin; Block Kit Builder exports work as-is)
cicd notify slack --channel C0123ABC --text "fallback for notifications" --blocks @release.json
# raw chat.postMessage args for anything without a flag (explicit flags win)
cicd notify slack --channel C0123ABC --text hi --body '{"metadata": {"event_type": "release", "event_payload": {}}}'
cicd notify slack ... --dry-run # print the payload, send nothing (no token needed)
On success it prints {"channel": "<ID>", "ts": "<ts>"} and writes channel/ts to $GITHUB_OUTPUT, so a
later step can reply in the thread (--thread-ts, --reply-broadcast) or edit the message
(--update <ts> with the channel ID). Also: --attachments (legacy, e.g. color bars), --username,
--icon-emoji/--icon-url (need chat:write.customize), --[no-]unfurl-links, --[no-]unfurl-media.
Slack errors exit 1 with a hint and do not trigger the build-failure alert.
Virtual desktops (cicd desktop)
Self-serve Windows/Linux desktops on EC2 with Amazon DCV, for QA of the Cozmo desktop app. The backing infra
(VPCs, launch templates, AMIs, SSM documents, idle-stop Lambda) lives in the allfly-cozmo repo; see its
docs/VIRTUAL_DESKTOPS.md. Each engineer runs the CLI with their own AWS SSO profile for cozmo-dev.
Prerequisites (cicd desktop init checks them):
- AWS CLI v2 and an SSO profile for the cozmo-dev account with the CozmoDesktopUser permission set
- session-manager-plugin
uv tool install af-cicd==0.5.0
cicd desktop init # profile + fastest region -> ~/.config/af-cicd/desktop.json
cicd desktop flavors # flavors and app versions available in your region
cicd desktop create qa-win --flavor windows-x64 # prints + saves the password, offers to connect
cicd desktop connect qa-win # SSM tunnel + DCV in your browser; q/Ctrl-C to close
| Command | What it does |
|---|---|
init |
Pick your profile and default region (by latency), check prerequisites |
ping |
TCP latency to each desktop region, fastest first (works without credentials) |
flavors [--region R] |
Flavors, and the app versions (AMIs) available per flavor; * marks the current default |
create NAME --flavor F [--region R] [--app-version X] [--instance-type T] [--connect/--no-connect] |
Launch, wait for SSM, set and print a password, then offer to connect (asks only on a terminal) |
list [--all] |
Your desktops in every region (--all: everyone's) |
describe NAME |
Details, plus when the idle auto-stop will kick in |
start NAME / stop NAME |
Start or stop and wait for the new state (stopped desktops keep their disk) |
connect NAME [--no-open] |
Start if needed, tunnel DCV to a free local port, open DCV's web client in your browser (--no-open: print the URL only). Shows the login user and saved password; while open p copies the password, q closes |
password NAME |
Set a new random password and print it |
keep-awake NAME --hours H / --off |
Skip the idle auto-stop for up to the configured maximum hours |
reset NAME [--app-version X] [--yes] |
Replace the disk with a fresh image (current, or a given app version) and print a new password |
delete NAME [--yes] |
Terminate the desktop and its disk |
Every AWS command takes --profile (default $AWS_PROFILE, then the saved profile) and re-runs
aws sso login when the SSO session has expired. Desktops are stopped after the configured idle time
(60 min by default) without a DCV connection; connect starts them again. Every password the CLI sets
(create, password, reset) is printed and saved to ~/.config/af-cicd/desktop.json (mode 0600, keyed by
instance ID) so connect can show it; delete removes it. Exit codes: 0 ok, 1 AWS/runtime error, 2 bad arguments.
Metadata
Release files for af-cicd 0.6.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| af_cicd-0.6.2.tar.gz | 94.1 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| af_cicd-0.6.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 233.1 kB
Release files / af_cicd-0.6.2.tar.gz
| Download URL | af_cicd-0.6.2.tar.gz |
|---|---|
| Size | 94.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
75b108a8e007dcd61ab95de4e1c1aa0e2ad161400cf3fa50beafc1dc9a9adbfd
|
|
BLAKE2b-256 checksum How to use checksums |
3b7a10181357677735b633aa1047a9ac5b34cc3fd6af47cedbd84bc871374fb3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / af_cicd-0.6.2-py3-none-any.whl
| Download URL | af_cicd-0.6.2-py3-none-any.whl |
|---|---|
| Size | 139.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fe7b39d4c24140e0a0bdd5213db2c1a85414c603185773089a560e4b441a9658
|
|
BLAKE2b-256 checksum How to use checksums |
2c3998f20ce83c67295a4761e1998b76c92ff6d71a13d54bbf8abcadda8c15f7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logSecurity for af-cicd 0.6.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for af_cicd-0.6.2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.