From 7bc8101bab7aef0e3b2760e5ebf6dd02ff71390f Mon Sep 17 00:00:00 2001 From: Jerry Date: Thu, 16 Jul 2026 18:15:00 -0400 Subject: [PATCH] Add setup skill and How to deploy README section - New .warp/skills/setup/SKILL.md: idempotent setup flow that clones or reuses an existing checkout, verifies required tools, creates .env, guides configuration, and validates credentials - README: add How to deploy section with a copy-pasteable Warp prompt, keep manual steps and rename variable docs to Configuration reference - .env.example: quote values containing spaces so sourcing works Co-Authored-By: Oz --- .env.example | 4 +- .warp/skills/setup/SKILL.md | 138 ++++++++++++++++++++++++++++++++++++ README.md | 44 ++++++++---- 3 files changed, 171 insertions(+), 15 deletions(-) create mode 100644 .warp/skills/setup/SKILL.md diff --git a/.env.example b/.env.example index eeca9e4..e854e81 100644 --- a/.env.example +++ b/.env.example @@ -38,7 +38,7 @@ DIGEST_CHANNEL=stable # --- Release conventions (optional; defaults shown) --- # Space-separated, ordered list of release channels. Cherry-picks run in this order. -RELEASE_CHANNELS=preview stable +RELEASE_CHANNELS="preview stable" # Per-channel release-branch path prefix. "{channel}" is replaced with a channel name, # e.g. stable -> stable_release/ # Example: preview_release/, stable_release/. Customize to your team's branch naming. @@ -50,7 +50,7 @@ DEFAULT_BRANCH=main CHERRYPICK_BRANCH_PREFIX=cherrypick/ # Name of the GitHub Actions workflow that cuts a release candidate. # Set to the exact name of your GitHub Actions workflow. -RC_WORKFLOW_NAME=Cut New Release Candidate +RC_WORKFLOW_NAME="Cut New Release Candidate" # Commit trailer key identifying a synced commit's public origin (public<->internal sync). # Trailer used to link commits back to the source repo, if you sync from a private repo. SYNC_TRAILER_KEY=Repo-Sync-Origin diff --git a/.warp/skills/setup/SKILL.md b/.warp/skills/setup/SKILL.md new file mode 100644 index 0000000..ae0ead4 --- /dev/null +++ b/.warp/skills/setup/SKILL.md @@ -0,0 +1,138 @@ +--- +name: setup +description: Set up the Client Release Agent end to end — clone the repo (or reuse an existing clone), verify required tools, create and fill in .env, and validate credentials. Use when the user asks to run the setup skill, or to set up, install, configure, or deploy the client release agent. +--- + +# setup + +Get the Client Release Agent working from scratch. This skill is **idempotent**: it works whether the repo is already cloned or not, and never overwrites an existing `.env`. + +Repo: `https://github.com/warpdotdev/client-release-agent-oss.git` + +## Step 1: Locate or clone the repo + +Check whether you are already inside a clone: + +```bash +git remote get-url origin 2>/dev/null | grep -q 'client-release-agent-oss' && echo "already in repo" +``` + +- If already inside the repo, use the current directory as `AGENT_DIR` and continue. +- Otherwise, check the default location, then clone if needed: + +```bash +AGENT_DIR="$HOME/client-release-agent-oss" +if [ -d "$AGENT_DIR/.warp/skills" ]; then + echo "existing clone found at $AGENT_DIR" +else + git clone https://github.com/warpdotdev/client-release-agent-oss.git "$AGENT_DIR" +fi +cd "$AGENT_DIR" +``` + +If the user wants the repo somewhere else, use their path instead. All later steps run from `AGENT_DIR`. + +## Step 2: Verify required tools + +Check for each required tool: + +```bash +for tool in git gh jq curl; do + command -v "$tool" >/dev/null || echo "MISSING: $tool" +done +``` + +If anything is missing, offer to install it (e.g. `brew install gh jq` on macOS, or the appropriate package manager). Then verify GitHub CLI authentication: + +```bash +gh auth status +``` + +If not authenticated, ask the user to run `gh auth login` (interactive — let them complete it) before continuing. + +## Step 3: Create .env + +Never overwrite an existing `.env`: + +```bash +if [ -f .env ]; then + echo ".env already exists — will fill in missing values only" +else + cp .env.example .env +fi +``` + +## Step 4: Fill in configuration + +Ask the user **which skills they plan to use** so you only require the relevant variables: + +- **Release skills** (`cherrypick-to-release`, `cut-new-release-candidate`, `post-release-status`): `INTERNAL_REPO`, `REPO_DIR`, `GITHUB_ORG`, `SLACK_BOT_TOKEN`, `ONCALL_SLACK_GROUP`, `RELEASE_SLACK_CHANNEL`, optionally `PUBLIC_REPO`. +- **Sentry digest** (`post-daily-new-issues`): `SENTRY_AUTH_TOKEN`, `SENTRY_ORG`, `SENTRY_PROJECT`, `SENTRY_PROJECT_ID`, `RELEASE_SLACK_CHANNEL`, `ONCALL_SLACK_GROUP`, optionally `RELEASE_VERSIONS_URL`. +- **Slack replies** (`respond-to-slack-thread`): `SLACK_BOT_TOKEN` only. + +The release-convention variables (`RELEASE_CHANNELS`, `RELEASE_BRANCH_PREFIX`, `DEFAULT_BRANCH`, `CHERRYPICK_BRANCH_PREFIX`, `RC_WORKFLOW_NAME`, `SYNC_TRAILER_KEY`, `DIGEST_CHANNEL`, status emoji) all have sensible defaults — only ask about them if the user says their conventions differ. See the repo `README.md` for the full variable reference. + +Collect the **non-secret** values conversationally and write them into `.env` with edits. For **secrets** (`SLACK_BOT_TOKEN`, `SENTRY_AUTH_TOKEN`): + +- **Never** ask the user to paste a token into the chat, and never echo a token in a command. +- Tell the user to edit `.env` themselves and paste the tokens in directly, then confirm when done. +- Token guidance: + - Slack: create a bot token (`xoxb-…`) at https://api.slack.com/apps with scopes `channels:read`, `channels:history`, `chat:write`, `chat:update`, `usergroups:read`, `users:read`, `users:read.email`. Install the app to the workspace and invite the bot to `RELEASE_SLACK_CHANNEL`. + - Sentry: create an auth token with `event:read` and `project:read` at Sentry → Settings → Auth Tokens. + +## Step 5: Load the environment + +```bash +set -a; source .env; set +a +``` + +Run this in the current session, and tell the user they'll need it in any future session that runs the skills (they can add it to their shell profile, CI, or scheduled-agent environment). Do not print the loaded values. + +## Step 6: Validate + +Run only the checks relevant to the skills the user selected. Print pass/fail per check without revealing secrets. + +**Slack token:** + +```bash +curl -s -H "Authorization: Bearer $SLACK_BOT_TOKEN" \ + "https://slack.com/api/auth.test" | jq '{ok, team, error}' +``` + +**Sentry token:** + +```bash +curl -fsS -H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \ + "https://sentry.io/api/0/projects/${SENTRY_ORG}/${SENTRY_PROJECT}/" | jq '{slug, id}' +``` + +Also confirm `.id` matches `SENTRY_PROJECT_ID`; if not, correct it in `.env`. + +**GitHub access to the release repo:** + +```bash +gh repo view "$INTERNAL_REPO" --json nameWithOwner --jq '.nameWithOwner' +``` + +**Local checkout (`REPO_DIR`):** + +```bash +git -C "$REPO_DIR" remote get-url origin +``` + +The origin should match `INTERNAL_REPO`. If `REPO_DIR` doesn't exist, offer to clone `INTERNAL_REPO` there: + +```bash +gh repo clone "$INTERNAL_REPO" "$REPO_DIR" +``` + +If any check fails, explain the likely cause (bad token, missing scope, bot not in channel, wrong slug) and help fix it before finishing. + +## Step 7: Summarize + +Report which skills are ready to use given the configured variables, and show a couple of example prompts, e.g.: + +- `Cherry-pick PR #1234 into stable and preview` +- `Post the daily new-issues digest for on-call` + +Remind the user: `.env` is gitignored — never commit it. diff --git a/README.md b/README.md index 891a1bb..726a95f 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ override anything that differs in your setup. | Skill | What it does | |---|---| +| `setup` | One-time setup: clones the repo, checks prerequisites, fills in `.env`, and validates credentials. | | `cherrypick-to-release` | Cherry-picks a commit into one or more release branches and opens PRs assigned to the current on-call. | | `cut-new-release-candidate` | Triggers a "Cut New Release Candidate" GitHub Actions workflow on a release branch. | | `post-release-status` | Posts/updates a Slack message tracking the status of cherry-pick PRs for a release. | @@ -24,21 +25,38 @@ override anything that differs in your setup. Each skill lives in `.warp/skills//SKILL.md`. See the [Warp skills documentation](https://docs.warp.dev) for how skills are discovered and run. -## Requirements +## How to deploy -- [`gh`](https://cli.github.com/) (GitHub CLI), authenticated (`gh auth login`) -- [`jq`](https://jqlang.github.io/jq/) -- `curl` -- `git` -- A Slack bot token (for the Slack-related skills) -- A Sentry auth token (for the Sentry digest skill) +### With Warp (recommended) -## Configuration +Paste this prompt into [Warp](https://www.warp.dev) — it works whether or not you've +cloned the repo yet: -Configuration is supplied entirely through environment variables, in two groups. Copy -`.env.example` to `.env`, fill it in, and source it (or export the variables in your -shell / CI / scheduled-agent environment). **Never commit your `.env` file** — it is -already covered by `.gitignore`. +> Clone https://github.com/warpdotdev/client-release-agent-oss.git (or use my existing +> clone), then read and follow `.warp/skills/setup/SKILL.md` to set up the client +> release agent. + +If you already have the repo cloned and open in Warp, just ask: **"Run the setup +skill"**. The agent will verify prerequisites, walk you through `.env` configuration, +and validate your credentials. + +### Manually + +1. Install the prerequisites: [`gh`](https://cli.github.com/) (GitHub CLI), + [`jq`](https://jqlang.github.io/jq/), `curl`, and `git`. +2. Authenticate the GitHub CLI: `gh auth login`. +3. Clone this repo: `git clone https://github.com/warpdotdev/client-release-agent-oss.git` +4. Copy `.env.example` to `.env` and fill it in (see the + [Configuration reference](#configuration-reference)). You'll need a Slack bot token + for the Slack-related skills and a Sentry auth token for the Sentry digest skill. +5. Load the variables before running the skills: `set -a; source .env; set +a` + (or export them in your shell / CI / scheduled-agent environment). + +**Never commit your `.env` file** — it is already covered by `.gitignore`. + +## Configuration reference + +Configuration is supplied entirely through environment variables, in two groups: - **Environment-specific values** — identifiers and secrets for your org, repos, Slack workspace, and Sentry project. Set the ones used by the skills you run; a few are @@ -91,7 +109,7 @@ Grant your Slack bot token the union of scopes needed by the skills you use: ## Usage These are [Warp agent skills](https://docs.warp.dev), so you don't invoke them directly. -Set and source your environment variables (see [Configuration](#configuration)), then +Set and source your environment variables (see [How to deploy](#how-to-deploy)), then describe what you want to Warp's agent in plain language — the agent matches your request to a skill (via its `description`) and runs the documented steps.