# Wire Ci — Reference

## Navigation

| Lines | Section |
|-------|---------|
| 1 | Title |
| 3–20 | Navigation |
| 21–22 | Examples |
| 23–39 | Create CI for a Go project (TBR + optional deploy) |
| 40–49 | Create CI for a CLI tool (TBR only, no deploy) |
| 50–57 | Validate existing workflows (no generation) |
| 58–70 | Options |
| 71–79 | Integration with build-epic |
| 80–154 | Reference block 1 — test-build-release.yml (Go, excerpt) |
| 155–204 | Reference block 2 — deploy.yml (generic web app, excerpt) |
| 205–232 | Reference block 3 — CLI dogfood (big-release pattern) |
| 233–257 | Reference block 4 — validate script |
| 258–268 | Reference block 5 — dry-run |

## Examples

### Create CI for a Go project (TBR + optional deploy)

```bash
# Resolve forge + stack, then apply the bundled template
bash scripts/wire-ci.sh --detect
bash scripts/wire-ci.sh --apply

wire-ci --validate
wire-ci --dry-run
```

To use your own org templates instead of the bundled ones:

```bash
BIGPOWERS_CI_TEMPLATES=/path/to/your/templates bash scripts/wire-ci.sh --apply
```

### Create CI for a CLI tool (TBR only, no deploy)

```bash
bash scripts/wire-ci.sh --apply
# Edit release job to download build artifact — see big-release dogfood
# CLI/library repos: delete deploy.yml; the release job is terminal.

wire-ci --validate
```

### Validate existing workflows (no generation)

```bash
wire-ci --validate --check-only
```

---

## Options

| Flag | Description |
|------|-------------|
| `--validate` | Check YAML syntax, permissions, secrets, common pitfalls |
| `--dry-run` | Run workflows locally via `act` or dispatch via `gh` |
| `--check-only` | Only validate, do not generate new files |
| `--type <type>` | Force project type (skip auto-detection) |
| `--force` | Overwrite existing workflow files |
| `--no-deploy` | Skip deploy.yml even for hosted stacks |

---

## Integration with build-epic

When `wire-ci` is used as part of `build-epic`:

1. **During develop-tdd**: If the task modifies `.github/workflows/`, run `wire-ci --validate` as a CI dry-run sub-step
2. **During release-branch**: After push, run `gh run list --limit 1 --branch main --json status,conclusion` to verify CI passes

---

## Reference block 1 — test-build-release.yml (Go, excerpt)

```yaml
name: Test Build Release
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

permissions:
  contents: read

concurrency:
  group: pipeline-${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  lint:
    runs-on: ubuntu-22.04
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0  # v7.0.0
      - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16  # v6.5.0
        with:
          go-version: '1.22'
          cache: true
      - uses: golangci/golangci-lint-action@55c2c1448f86e01eaae002a5a3a9624417608d84  # v6.5.2
        with:
          version: v1.64.8

  test:
    needs: [lint]
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0  # v7.0.0
      - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16  # v6.5.0
        with:
          go-version: '1.22'
          cache: true
      - run: go vet ./...
      - run: go test ./... -count=1

  build:
    needs: [test]
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0  # v7.0.0
      - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16  # v6.5.0
        with:
          go-version: '1.22'
          cache: true
      - run: go build ./...
      - run: jq -n --arg sha "${{ github.sha }}" '{sha: $sha}' > deploy-meta.json
      - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a  # v7.0.1
        with:
          name: deploy-meta
          path: deploy-meta.json

  release:
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    needs: [build]
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0  # v7.0.0
        with:
          fetch-depth: 0
      - run: npx semantic-release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

---

## Reference block 2 — deploy.yml (generic web app, excerpt)

```yaml
name: Deploy
on:
  workflow_run:
    workflows: ["Test Build Release"]
    types: [completed]

permissions:
  contents: read
  actions: read

concurrency:
  group: deploy-production
  cancel-in-progress: false

env:
  SITE_URL: "https://CHANGE-ME.example.com"

jobs:
  deploy:
    if: >
      github.event.workflow_run.conclusion == 'success' &&
      github.event.workflow_run.head_branch == 'main'
    runs-on: ubuntu-22.04
    environment: production
    steps:
      - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c  # v8.0.1
        with:
          name: deploy-meta
          github-token: ${{ secrets.GITHUB_TOKEN }}
          run-id: ${{ github.event.workflow_run.id }}
          path: deploy-meta
      # Placeholder deploy step — bigpowers ships no deploy templates and pins
      # no third-party action. Substitute your platform's own step here, or drop
      # the deploy job entirely for CLI and library repos. Pin whatever action
      # you choose to a full commit SHA rather than a tag. (GH #104)
      - name: Deploy
        run: |
          echo "Replace this step with your platform's deploy command."
          echo "commit=$(jq -r .sha deploy-meta/deploy-meta.json)"
          exit 1
      - name: Health check
        run: |
          curl -sf "${{ env.SITE_URL }}" || exit 1
```

---

## Reference block 3 — CLI dogfood (big-release pattern)

```yaml
  build:
    needs: [test]
    steps:
      - run: make build
      - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a  # v7.0.1
        with:
          name: big-release-${{ github.sha }}
          path: bin/big-release

  release:
    needs: [build]
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    steps:
      - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c  # v8.0.1
        with:
          name: big-release-${{ github.sha }}
          path: bin
      - run: make release   # cross-compile assets only; host binary from artifact
      - run: big-release release --verbose
```

No `deploy.yml` — CLI publishes via the release job.

---

## Reference block 4 — validate script

```bash
for f in .github/workflows/*.yml .github/workflows/*.yaml; do
  [ -f "$f" ] || continue
  python3 -c "import yaml; yaml.safe_load(open('$f'))" || echo "FAIL: $f has YAML syntax errors"
done

for f in .github/workflows/test-build-release.yml; do
  if grep -q "permissions:" "$f"; then
    echo "OK: $f has permissions block"
  else
    echo "WARNING: $f missing permissions block"
  fi
done

if grep -q 'workflows: \["Test Build Release"\]' .github/workflows/deploy.yml 2>/dev/null; then
  if ! grep -q 'name: Test Build Release' .github/workflows/test-build-release.yml; then
    echo "WARNING: deploy.yml listens for Test Build Release but TBR name may differ"
  fi
fi
```

---

## Reference block 5 — dry-run

```bash
if command -v act &>/dev/null; then
  act push --dry-run -W .github/workflows/test-build-release.yml
elif command -v gh &>/dev/null; then
  gh workflow run test-build-release.yml --ref "$(git branch --show-current)"
else
  echo "Install act or gh for dry-run"
fi
```
