-
Notifications
You must be signed in to change notification settings - Fork 0
Pipeline Plan 204
Plan written to .claude/pipeline-artifacts/plan.md.
Summary of the plan:
Approach: Add quickstart subcommand to existing sw-ci.sh (Approach B) — keeps CI logic in the CI module with minimal blast radius. shipwright init --ci delegates to sw-ci.sh quickstart.
6 files touched:
-
New:
scripts/lib/ci-quickstart.sh— core library with detection, YAML generation, README section -
Modified:
sw-ci.sh(routing + orchestrator),sw-init.sh(--ciflag),sw-doctor.sh(--civalidation),sw-ci-test.sh(9 new tests),sw-doctor-test.sh(2 new tests)
Key design decisions:
- Reuses existing
detect_repo_environments_json()+default_test_cmd_for_environment()for project detection - Generated workflows include issue label triggers, secrets checks, artifact upload, status reporting
- Default templates:
fast+standard; override with--template - Safe by default: skips existing files unless
--force - Bash 3.2 compatible throughout (no
${var^}, usetrinstead)
9 tasks, 12+ tests covering happy path, error cases, and edge cases.
section with usage instructions and badge auto-generated
5. shipwright doctor --ci validates workflow configuration
6. Works with NO_GITHUB=1 for air-gapped testing
Approach A: Extend sw-init.sh with --ci flag
- Add
--ciflag parsing tosw-init.sh, add a CI section that calls into a newlib/ci-quickstart.shlibrary - Pros: Single entry point for all init, reuses existing flag parsing and test infrastructure
- Cons:
sw-init.shis already 500+ lines, adding more makes it harder to maintain
Approach B: New sw-ci.sh quickstart subcommand (CHOSEN)
- Add a
quickstartsubcommand to the existingsw-ci.shscript, plus wireshipwright init --cito delegate to it - Pros: CI generation logic stays in the CI module,
sw-init.shstays focused on local setup, reuses existingsw-ci.shrouter and helpers - Cons: Two entry points (
init --ciandci quickstart), but this is consistent with how other commands delegate (e.g.,initcallsdoctorat the end) -
Why chosen: Minimal blast radius. The
sw-ci.shscript already handles workflow generation. Addingquickstartis a natural extension. The--ciflag insw-init.shis just a 3-line delegation.
Approach C: Standalone sw-ci-quickstart.sh script
- New top-level script with its own routing
- Pros: Complete isolation
- Cons: Duplicates boilerplate, adds another script to maintain, inconsistent with existing patterns
| Risk | Impact | Mitigation |
|---|---|---|
| Generated YAML has syntax errors | Users get broken CI | Validate generated YAML using existing cmd_validate() before writing |
| Project detection misidentifies type | Wrong test command in workflow | Use existing detect_repo_environments_json() which is battle-tested; add a --test-cmd override flag |
Bash 3.2 compat issues (e.g., ${var^} in existing cmd_generate()) |
macOS users hit errors | Avoid case-modification syntax; use tr for case conversion |
| Overwriting user's existing workflows | Lost customizations | Check for existing files, warn and skip (or --force to overwrite) |
NO_GITHUB=1 not respected in new code |
Air-gapped environments break | Test explicitly with NO_GITHUB=1, skip any gh API calls when set |
Depends on (existing, stable):
-
scripts/lib/pipeline-detection.sh—detect_repo_environments_json(),default_test_cmd_for_environment() -
scripts/sw-ci.sh— Router, helpers, existing workflow generation -
scripts/sw-init.sh— Will add--ciflag delegation -
scripts/sw-doctor.sh— Will add--civalidation checks -
templates/pipelines/*.json— Pipeline template definitions -
scripts/lib/helpers.sh—info(),success(),warn(),error(),emit_event() -
scripts/lib/test-helpers.sh— Test infrastructure
Depended on by:
- Nothing yet (new feature)
No circular dependency risks.
+------------------------------------------------------+
| User Entry Points |
| shipwright init --ci shipwright ci quickstart |
+----------+-----------------------------------+-------+
| delegates | direct
v v
+------------------------------------------------------+
| sw-ci.sh :: cmd_quickstart() |
| Orchestrates: detection -> template -> generate |
+------+----------+----------+----------+--------------+
| | | |
v v v v
+----------++----------++----------++------------------+
| pipeline-|| templates/|| generate || cmd_validate() |
|detection || pipelines/|| _quick || (existing) |
|.sh || *.json || _yaml() || |
|(existing)||(existing) || (new) || |
+----------++----------++----------++------------------+
// cmd_quickstart(templates?: string, test_cmd?: string, force?: boolean): void // - templates: comma-separated list of template names (default: "fast,standard") // - test_cmd: override auto-detected test command // - force: overwrite existing workflow files // Exits 0 on success, 1 on error // Side effects: writes .github/workflows/shipwright-*.yml, emits events // generate_quickstart_workflow(template_name: string, test_cmd: string, project_type: string): string // - Returns YAML content for a single workflow file // Pure function (no side effects) // detect_project_for_ci(): { env_id: string, test_cmd: string } // - Wraps detect_repo_environments_json() + default_test_cmd_for_environment() // - Returns first detected environment and its test command // generate_readme_section(templates: string[], owner: string, repo: string): string // - Returns markdown snippet for README with badges and usage // doctor_check_ci(): void // - Validates .github/workflows/shipwright-*.yml files exist and are valid // - Checks secrets references, trigger configuration
1. User runs `shipwright init --ci` or `shipwright ci quickstart`
2. cmd_quickstart() parses flags (--template, --test-cmd, --force)
3. detect_project_for_ci() runs pipeline-detection to find project type + test cmd
4. For each requested template (fast, standard, full, autonomous):
a. Read templates/pipelines/{template}.json for stage list
b. generate_quickstart_workflow() builds YAML with:
- Issue label trigger (on.issues.types: [labeled])
- Push/PR triggers
- Secrets check step
- Detected test command
- Artifact upload step
- Status reporting
c. Write to .github/workflows/shipwright-{template}.yml (atomic write)
d. Validate with cmd_validate()
5. generate_readme_section() creates badge markdown
6. Print summary with next steps
- Detection errors: If no project type detected, warn and use generic placeholder
- Template not found: Error and exit 1 with message listing available templates
-
File write errors: Caught by
set -euo pipefail+ ERR trap -
Existing file conflicts: Skip with warning unless
--force
-
scripts/lib/ci-quickstart.sh— Core quickstart generation library (~200 lines)-
detect_project_for_ci()— Project detection wrapper -
generate_quickstart_workflow()— YAML generation per template -
generate_readme_section()— README badge/usage snippet
-
-
scripts/sw-ci.sh— Addquickstartsubcommand routing +cmd_quickstart()orchestrator (~40 lines) -
scripts/sw-init.sh— Add--ciflag parsing + delegation (~10 lines) -
scripts/sw-doctor.sh— Add--civalidation mode (~30 lines) -
scripts/sw-ci-test.sh— Add quickstart tests (~80 lines) -
scripts/sw-doctor-test.sh— Add--cidoctor tests (~20 lines)
Core library with:
- Source guard pattern (
_CI_QUICKSTART_LOADED) -
detect_project_for_ci(): callsdetect_repo_environments_json(), picks first env, gets test cmd viadefault_test_cmd_for_environment() -
generate_quickstart_workflow(): builds complete GitHub Actions YAML for a given template including:-
on:triggers (issues labeled, push to main, PR to main, workflow_dispatch) -
env:section withSHIPWRIGHT_PIPELINEandNO_GITHUBsupport - Jobs:
setup(checkout, install deps, secrets check),pipeline(run shipwright pipeline with template) - Artifact upload step for
.claude/pipeline-artifacts/ - Status reporting step
-
-
generate_readme_section(): builds markdown with badges and usage instructions
- Add
cmd_quickstart()orchestrator function that:- Sources
lib/ci-quickstart.shandlib/pipeline-detection.sh - Parses
--template,--test-cmd,--forceflags - Calls
detect_project_for_ci()to get project type + test command - Loops over templates, calls
generate_quickstart_workflow()for each - Writes files atomically (tmp + mv)
- Validates each generated file
- Prints README section + summary
- Sources
- Add
quickstart)to the case statement router - Update help text with quickstart subcommand
Add --ci flag:
- Parse
--ciin the existing flag loop - When set, exec into
"$SCRIPT_DIR/sw-ci.sh" quickstart "$@"(passing remaining args) - Update help text
Add to sw-doctor.sh:
- Parse
--ciflag -
doctor_check_ci()function:- Check
.github/workflows/shipwright-*.ymlfiles exist - Validate each with basic structure check (name, on, jobs present)
- Check for required secrets references
- Check trigger configuration includes issue label trigger
- Check
Add to sw-ci-test.sh:
- Test quickstart generates workflow files for default templates
- Test generated YAML has correct structure (name, on, jobs, steps)
- Test workflow includes issue label trigger
- Test workflow includes artifact upload step
- Test project detection maps node ->
npm test - Test
--forceoverwrites existing files - Test skip behavior when files exist without
--force - Test
--templateflag selects specific templates - Test README section output includes badge markdown
Add to sw-doctor-test.sh:
- Test
--ciflag detects missing workflows - Test
--ciflag passes with valid workflows
Run npm test and fix any failures.
- Task 1: Create
scripts/lib/ci-quickstart.shwithdetect_project_for_ci()function - Task 2: Add
generate_quickstart_workflow()to produce complete workflow YAML per template - Task 3: Add
generate_readme_section()for badge and usage markdown - Task 4: Add
cmd_quickstart()orchestrator tosw-ci.sh+ wire routing + update help - Task 5: Add
--ciflag tosw-init.shthat delegates tosw-ci.sh quickstart - Task 6: Add
doctor_check_ci()tosw-doctor.shfor--civalidation - Task 7: Add quickstart tests to
sw-ci-test.sh(generation, YAML structure, detection) - Task 8: Add doctor
--citests tosw-doctor-test.sh - Task 9: Run full test suite and fix any failures
Task dependencies: Tasks 1-3 build the library sequentially. Task 4 depends on Tasks 1-3. Tasks 5, 6 depend on Task 4. Tasks 7, 8 depend on Tasks 4-6. Task 9 depends on all.
-
Unit tests (8): Individual function outputs in
sw-ci-test.sh-
detect_project_for_ci()returns correct env for node/python/go/rust projects -
generate_quickstart_workflow()produces valid YAML structure -
generate_readme_section()includes correct badge URLs -
cmd_quickstart()creates expected files
-
-
Integration tests (4): End-to-end flow in
sw-ci-test.sh- Full quickstart flow creates all workflow files
-
--forceflag behavior -
NO_GITHUB=1compatibility - Doctor
--civalidates generated workflows
- E2E tests (0): Not adding new E2E — integration tests cover the critical path
- 100% of
cmd_quickstart()branches (force/no-force, existing/new files) - All supported project types mapped (node, python, go, rust, ruby, java, fallback)
- Generated YAML validated for structure (triggers, jobs, steps)
Happy path: shipwright ci quickstart in a node project -> generates shipwright-fast.yml and shipwright-standard.yml with npm test command
Error cases:
- No project type detected -> generates workflow with placeholder test command + warning
- Template not found -> exits 1 with helpful error message
Edge cases:
- Existing workflow files -> skips with warning (no
--force) -
NO_GITHUB=1set -> all functions work, noghAPI calls - Empty repository (no package.json, no Cargo.toml, etc.) -> graceful fallback
Primary: As a CI-first developer, I want to run shipwright init --ci so that I get ready-to-use GitHub Actions workflows without manually writing YAML, cutting my setup time from 30min to under 5min.
Secondary: As a DevOps engineer validating CI setup, I want to run shipwright doctor --ci so that I can verify my workflow configuration is correct before pushing to GitHub.
-
Given a Node.js project with
package.json, When I runshipwright init --ci, Then.github/workflows/shipwright-fast.ymlandshipwright-standard.ymlare created withnpm testas the test command. -
Given existing workflow files, When I run
shipwright init --ciwithout--force, Then existing files are preserved and I see a warning message. -
Given
NO_GITHUB=1is set, When I runshipwright init --ci, Then workflows are generated successfully with no GitHub API calls. -
Given workflows generated by quickstart, When I run
shipwright doctor --ci, Then all checks pass.
- Empty state: No project markers found -> generates workflows with a placeholder and warns the user to update
- Error state: Invalid template name -> clear error listing available templates
-
Overload state: User runs in a monorepo with multiple project types -> picks first detected, mentions others so user can override with
--test-cmd
| Approach | Complexity | Performance | Maintainability | Blast Radius |
|---|---|---|---|---|
| A: Extend sw-init.sh directly | Low | Same | Lower (bloats init) | Medium |
| B: sw-ci.sh quickstart (chosen) | Medium | Same | High (separation) | Low |
| C: Standalone script | Medium | Same | Lower (duplication) | Low |
Chose B because it keeps CI logic in the CI module, minimizes changes to existing files, and follows the codebase pattern of composable subcommands.
| Risk | What Could Break | Mitigation |
|---|---|---|
Bash 3.2 ${var^} usage |
macOS users on default bash | Use tr for case conversion |
jq not available |
Workflow generation fails | Check early, provide clear error |
| Pipeline template schema changes | Generated YAML becomes stale | Read templates dynamically |
| Tests flaky on CI | False failures | Use deterministic mocks, no sleep |
| Overwriting user workflows | Lost CI config | Default skip-existing + --force opt-in |
-
shipwright init --cigenerates.github/workflows/shipwright-{fast,standard}.ymlby default -
shipwright ci quickstartworks as a direct entry point - Generated workflows include: issue label trigger, push/PR triggers, secrets check, artifact upload, status reporting
- Auto-detects project type (node/python/rust/go/ruby/java) and includes correct test command
-
--templateflag allows selecting specific templates -
--test-cmdflag allows overriding detected test command -
--forceflag allows overwriting existing workflow files - README section with badges is printed to stdout
-
shipwright doctor --civalidates workflow configuration - Works with
NO_GITHUB=1(no GitHub API calls) - All new code is Bash 3.2 compatible
- All existing tests continue to pass
- New tests cover happy path, error cases, and edge cases (12+ test cases)