Skip to main content

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.yml workflow.
  • To release:
    • Ensure all your features are ready on master
    • Trigger the publish.yml workflow with workflow_dispatch and choose patch, minor, or major for bump.
      • The workflow runs uv version --bump to auto-rev the version, commits pyproject.toml + uv.lock, tags vX.Y.Z, then builds with uv build and publishes to PyPI.

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

  1. GitHub CLI: Install the GitHub CLI tool

    # macOS
    brew install gh
    
    # Ubuntu/Debian
    sudo apt install gh
    
    # Windows
    winget install GitHub.cli
    
  2. Authentication: Authenticate with GitHub

    gh auth login
    
  3. 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:

  1. Trigger the "Release" workflow on all three Quest v2 repositories:
    • allfly-quest-ui
    • allfly-quest-core-api
    • gds-api
  2. Promote code from develop branch to qa
  3. Provide real-time status updates and links to monitor progress
  4. 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 that uv can't resolve (e.g. another dependency caps the version) or that exceed max_bump are 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 (not GITHUB_TOKEN) so PR checks run on it.
  • Per-repo overrides (display name, base branch, max_bump, expiring ignores) live in .github/vscan.toml; see src/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 (or notify_clean = true in vscan.toml) to also post on clean runs. The reusable workflow posts its own alert if the job dies before cicd can 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.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for af-cicd 0.6.0
File Size Uploaded Provenance
af_cicd-0.6.0.tar.gz 94.1 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for af-cicd 0.6.0
File Interpreter ABI Platform
af_cicd-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 233.2 kB

Release files / af_cicd-0.6.0.tar.gz

Download URL af_cicd-0.6.0.tar.gz
Size 94.1 kB
Tags Source
SHA-256 checksum
How to use checksums
ae60caa945ec49e9a79bd70e41df0609ca84d49ff4f6648914e5e306729a1d27
BLAKE2b-256 checksum
How to use checksums
92058378be208e42d8232945ce96163ecfb9310f8b8c60b4b6764e949a229917
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 7, 2026.

Transparency log

Release files / af_cicd-0.6.0-py3-none-any.whl

Download URL af_cicd-0.6.0-py3-none-any.whl
Size 139.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
611338e5a15a4bd0a22e65f56854e5baefaba37038ba289b9a3e895fbfc982fe
BLAKE2b-256 checksum
How to use checksums
00576ca459d4de443a7b3a90dbfc0238772b9b31af1551e736d8bafb8fea22dd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 7, 2026.

Transparency log

Security for af-cicd 0.6.0

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.

Select from 2 files

Attestation for af_cicd-0.6.0.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 7, 2026.

Transparency log

A 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page