Skip to main content

swift-ci-scaffold

Scaffold the repo side of Xcode Cloud for an XcodeGen / Tuist Swift project - generate ci_scripts/ci_post_clone.sh (regen + guarded CI_BUILD_NUMBER stamping), propose a unit-test-only CI scheme, print the exact App Store Connect workflow checklist, and optionally install an opt-in .githooks/pre-push gate. Shows diffs and confirms before writing.

Ir para a instalação

Informações da origem

Repositório
charlesjones-dev/claude-code-plugins-dev
Última atividade na origem
3 de junho de 2026 às 04:52
Idioma detectado do SKILL.md
inglês
Estrelas
35
Forks
3

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
swift-ci-scaffold
description
Scaffold the repo side of Xcode Cloud for an XcodeGen / Tuist Swift project - generate ci_scripts/ci_post_clone.sh (regen + guarded CI_BUILD_NUMBER stamping), propose a unit-test-only CI scheme, print the exact App Store Connect workflow checklist, and optionally install an opt-in .githooks/pre-push gate. Shows diffs and confirms before writing.
argument-hint
[path] [--hook]
allowed-tools
["Bash","Read","Glob","Grep","Write","Edit","AskUserQuestion"]
disable-model-invocation
true
# Swift CI Scaffolder You prepare the **repo side** of Xcode Cloud for a generator-based Swift project, and you fix the two build-system blockers that `/swift-preflight` flags: a missing/weak `ci_post_clone.sh` and a static build number. You also optionally install a local pre-push gate. You **cannot** create or edit the Xcode Cloud workflow itself - those live in App Store Connect, not the repo. You scaffold what the repo can hold and print the exact UI steps for the rest. ## Rules - **Non-destructive.** Probe first, propose a diff, confirm, then write. Never overwrite an existing `ci_post_clone.sh`, `project.yml`, or hook without showing the change and getting a yes. - **Preserve the source of truth.** On XcodeGen, edits go into `project.yml`, never the pbxproj. Read the real deployed bundle id / team from the pbxproj first and make sure `project.yml` already carries them (if not, tell the user to reconcile - see `/swift-preflight` Check 1 - before you scaffold a regen step, because regen would otherwise revert their signing identity). - **Idempotent.** If a well-formed script/scheme/hook already exists, say so and offer to only patch the missing pieces. ## Arguments `$ARGUMENTS`: optional `path` (repo root, default cwd); `--hook` jumps straight to the pre-push hook step. ## Phase 0: Probe Detect the generator (xcodegen / tuist), platforms, existing `ci_scripts/`, the app + unit-test + UI-test targets, and the current `CURRENT_PROJECT_VERSION`. If the project is a plain `.xcodeproj` (no generator) or SwiftPM library, tell the user this scaffolder is for generator-based app projects on Xcode Cloud and stop (offer `/swift-verify` instead). **Critical pre-check (XcodeGen drift):** before proposing a regen-on-CI script, confirm `project.yml` already declares the real `PRODUCT_BUNDLE_IDENTIFIER` and `DEVELOPMENT_TEAM` that the pbxproj uses: ```bash grep -E 'PRODUCT_BUNDLE_IDENTIFIER|DEVELOPMENT_TEAM' *.xcodeproj/project.pbxproj | sort -u ``` If `project.yml` is missing either, **stop and warn**: adding a CI regen step now would revert the hand-set signing identity and break the App Store record. Have the user copy the real values into `project.yml` `settings.base` first. ## Phase 1: `ci_scripts/ci_post_clone.sh` If absent or malformed, propose this (adapt generator and stamp target): ```sh #!/bin/sh # Xcode Cloud runs this immediately after cloning, before it resolves # dependencies or reads the Xcode project. The .xcodeproj is generated from # project.yml by XcodeGen, so we regenerate here to guarantee the build matches # the spec (no stale/hand-edited pbxproj drift). We also stamp the build number # from CI_BUILD_NUMBER so each TestFlight upload is unique. set -e # Xcode Cloud starts in ci_scripts/; the repo root is one level up. cd "$CI_PRIMARY_REPOSITORY_PATH" echo "Installing XcodeGen..." brew install xcodegen # Stamp the build number into the spec BEFORE generating, so the generated # project carries a unique CFBundleVersion. Guarded so local builds (where # CI_BUILD_NUMBER is unset) keep the spec value. if [ -n "$CI_BUILD_NUMBER" ]; then echo "Setting CURRENT_PROJECT_VERSION to $CI_BUILD_NUMBER" /usr/bin/sed -i '' \ "s/^\( *CURRENT_PROJECT_VERSION:\).*/\1 \"$CI_BUILD_NUMBER\"/" \ project.yml fi echo "Generating Xcode project..." xcodegen generate echo "ci_post_clone complete." ``` After writing, set the executable bit: `chmod +x ci_scripts/ci_post_clone.sh`. Notes to surface: - The `sed` form above matches a `CURRENT_PROJECT_VERSION:` line in `project.yml`. If the project version lives elsewhere (a base xcconfig, or only in the pbxproj), adapt the stamp target and tell the user. - For **Tuist**, swap `brew install xcodegen` + `xcodegen generate` for `brew install tuist` + `tuist generate`, and stamp wherever the version is declared. - Do **not** also enable App Store Connect auto-increment; pick one source of truth (this script). ## Phase 2: Unit-test-only CI scheme If a UI-test target exists and no unit-test-only shared scheme is present, propose adding one to `project.yml` `schemes:` (so it generates as shared). Example shape: ```yaml schemes: App-CI: build: targets: App: all AppTests: [test] test: targets: - AppTests # unit only — no AppUITests, so a flaky UITest can't gate a release run: config: Debug archive: config: Release ``` Explain: point the Xcode Cloud Test actions (iOS + macOS) at `App-CI`, keep the Archive action on the full `App` scheme. The scheme is only visible to Xcode Cloud **after** the commit that defines it is pushed. ## Phase 3: App Store Connect workflow checklist (print, cannot automate) ``` App Store Connect → your app → Xcode Cloud → Manage Workflows. Repo cannot hold these: 1. Start Conditions: Branch Changes on your release branch (e.g. `staging` or `main`). 2. Environment: select the Xcode version matching project.yml `xcodeVersion`. 3. Test action (iOS): scheme = App-CI, "Required to Pass". Repeat for macOS if you ship Mac. 4. Archive action: scheme = App (full), one per platform you distribute. 5. Skip Build and Analyze actions — Archive already does a full signed release build, and the Clang analyzer adds near-zero value for pure Swift (strict concurrency + swiftlint cover it). 6. Post action: TestFlight (internal) for iOS and/or macOS. 7. First run will surface environment-only test failures that pass locally (headless keychain writes). Fix test-side — see /swift-preflight Check 5 — not in production. ``` ## Phase 4: Opt-in pre-push hook (only if user agrees, or `--hook`) Offer, never force. If yes, write `.githooks/pre-push` (version-controlled, like a `.githooks/` convention) that runs the local gate before a push: ```sh #!/bin/sh # Pre-push gate: regenerate, format-check, lint strict, unit tests. # Enable once per clone: git config core.hooksPath .githooks set -e exec ./scripts/verify.sh # or inline the /swift-verify pipeline if no verify.sh exists ``` If there is no `scripts/verify.sh`, inline the detected pipeline (xcodegen generate -> swiftformat --lint -> swiftlint --strict -> xcodebuild test on the cheapest destination). `chmod +x .githooks/pre-push`. Then tell the user to run `git config core.hooksPath .githooks` once per clone, and that `--no-verify` bypasses it (discouraged - fix the failure instead). Do not auto-run `git config`; that changes their git setup - tell them the command. ## Output Summarize what was written (with the diff already shown and confirmed), what was skipped because it already existed, and the remaining manual App Store Connect steps. End by suggesting a re-run of `/swift-preflight` to confirm the FAILs cleared.
Ver no GitHub