Install
$ agentstack add skill-cboone-agent-harness-plugins-set-up-ci ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Set-Up CI
Detect the project's language(s), create a GitHub Actions CI workflow with appropriate parallel jobs (test, lint, format, vulnerability check), and create matching Makefile targets for local development.
Workflow
1. Detect Project Type
If the user specified a language in their request (e.g., go-cli, go-library, javascript, python, rust, ruby, shell, zig, zsh), use it directly instead of scanning for markers. Still perform sub-detection steps as needed (e.g., JS package manager detection for javascript, or verifying main.go/cmd/ for go-cli vs go-library).
Scan for language and file-type markers using Glob. Exclude node_modules/, .yarn/, vendor/, and other dependency directories from all searches to avoid false positives from vendored code.
| Marker(s) | Language | | ------------------------------------------------------------------------------------------------------------- | --------------------- | | go.mod | Go | | package.json + source files (*.js, *.ts, *.jsx, *.tsx, *.mjs, *.mts, excluding node_modules/) | JavaScript/TypeScript | | pyproject.toml, setup.py, requirements.txt | Python | | Cargo.toml | Rust | | build.zig, build.zig.zon | Zig | | Gemfile, *.gemspec | Ruby | | *.sh, bin/*, scripts/* | Shell | | *.zsh, #!/usr/bin/env zsh shebangs, .zshrc, .zshenv | Zsh |
Go sub-detection: If main.go exists at the root or a cmd/ directory exists, classify as Go CLI. Otherwise classify as Go Library.
JS/TS sub-detection: Determine the package manager from lockfiles:
package-lock.json= npmyarn.lockor.yarnrc.yml= yarnpnpm-lock.yaml= pnpmbun.lock= bun- Default to npm if no lockfile found.
Source file verification: When package.json is detected, verify that actual JavaScript or TypeScript source files exist (*.js, *.ts, *.jsx, *.tsx, *.mjs, *.mts, excluding node_modules/ and config files like eslint.config.js). A package.json used only for devDependencies (e.g., markdownlint tooling) does not make the project a JavaScript project. If no source files are found, skip JavaScript/TypeScript CI.
If multiple languages are detected, create a multi-language workflow with one job group per language. Present the detected languages to the user and confirm before proceeding.
If no language is detected, offer a generic workflow with make test and make lint targets.
2. Check for Existing CI
Look for existing CI files:
ls .github/workflows/ci.yml
ls .github/workflows/ci.yaml
ls .github/workflows/*.yml
If a CI workflow exists, present its contents and ask the user:
- Overwrite: Replace the existing CI workflow entirely
- Merge: Add missing jobs to the existing workflow (keep existing jobs intact)
- Abort: Stop without changes
3. Check for Existing Makefile
If a Makefile exists, scan for existing CI-relevant targets:
grep -E '^(test|lint|fmt|vet|vuln|build|cover|coverage|tidy|tools|all|deny|audit|typos|changelog):' Makefile
Report which targets already exist and which will be added. Only add targets that do not already exist. Ask before modifying any existing target.
If no Makefile exists, offer to create one with the appropriate language-specific Makefile reference (see ./references/makefile-.md). The Makefile provides standard targets for local development (test, lint, fmt, vuln, etc.) and is required by the Go CI reusable workflow (run-go-ci.yml@v3.0.0), which calls Makefile targets (make test, make vet, make fmt, etc.) directly. If the user declines, note that CI will fail for Go templates because the reusable workflow requires Makefile targets.
4. Create CI Workflow
Read the appropriate language CI reference under ./references/ci-.md and generate .github/workflows/ci.yml from it. Write the file using the Write tool. The .github/workflows/ directory will be created automatically if it does not exist.
Go, Rust, Zig, Shell, and secret scanning templates use cboone/gh-actions reusable workflows that handle tool installation, caching, and execution internally. Other language templates use inline jobs.
Ensure a Language Version File
The CI templates read language runtime versions from a project-owned version file rather than pinning inline:
| Language | Version source the workflow reads | Action if missing | | -------- | ------------------------------------------------ | --------------------------------------------------------------------------------- | | Node.js | .tool-versions (line nodejs ) | Create .tool-versions with nodejs and warn the user to commit it | | Ruby | .tool-versions (line ruby ) | Create .tool-versions (or append) with ruby | | Go | go.mod (go X.Y directive) | Always present in a Go project; no action needed | | Rust | rust-toolchain.toml (when present) | Create one with [toolchain] channel = "stable" if missing | | Python | pyproject.toml requires-python (uv reads it) | Ensure the constraint is present in pyproject.toml | | Zig | build.zig.zon minimum_zig_version | Always present in a Zig project; no action needed |
Before writing the CI workflow, check for the relevant version file and create or update it as needed. Latest LTS / stable lookups:
- Node.js LTS:
curl -s https://nodejs.org/dist/index.json | jq -r 'first(.[] | select(.lts != false)) | .version' | sed 's/^v//' - Latest stable Ruby:
gh api repos/ruby/ruby/releases --jq 'first(.[] | select(.prerelease == false)) | .tag_name' | sed 's/^v//; s/_/./g'(Ruby tags use bothv3.4.0andv3_4_0forms; the trailingsednormalizes them to the dotted format.tool-versionsexpects)
All templates share:
- Triggers: push to
main, pull requests targetingmain paths-ignorefor documentation and agent configuration changes- Concurrency groups to cancel in-progress runs on the same branch/PR
permissions: contents: readactions/checkout@v6(in inline jobs) or handled by reusable workflows
Runner Usage Notes
The paths-ignore patterns skip CI for changes that do not affect build or test outcomes:
*.mdmatches root-level Markdown only (README, CONTRIBUTING, etc.). Nested.mdfiles such as Scrut CLI tests intests/scrut/are NOT ignored, so CI still runs when test files change.docs/**skips documentation directory changes..claude/**,**/CLAUDE.md,**/AGENTS.mdskip AI agent configuration files.LICENSEand.editorconfigskip non-code metadata.
When to adjust: Remove *.md from paths-ignore if your project treats Markdown files as source code (e.g., documentation-focused projects where Markdown linting is a CI step). Remove docs/** if your docs directory contains generated API references that should trigger CI.
The concurrency group cancels in-progress CI runs when new commits are pushed to the same branch or PR. This prevents wasted minutes on superseded commits.
For multi-language projects, combine language-specific jobs into a single workflow file using the multi-language pattern in ./references/ci-multi-language.md.
5. Create or Update Makefile Targets
Read the appropriate language Makefile reference under ./references/makefile-.md and add missing targets from it. Include both targets that the CI workflow references directly (e.g., make test, make vet) and standard local-development targets (test, lint, fmt, vuln, etc.) even when the CI workflow runs equivalent commands directly rather than via make.
Rules:
- Only add targets that do not already exist in the Makefile
- Ask before modifying existing targets
- If creating a new Makefile, include a
helptarget - Preserve any existing Makefile content (append new targets at the end)
6. Summary
Print a summary of what was created or modified:
- List every file created or modified
- Suggest complementary plugins:
- The set-up-secret-scanning skill for secret scanning
- The set-up-linters skill for linter configuration (if no linter configs detected)
- The add-scrut-cli-tests skill for CLI snapshot testing (if CLI project detected)
- The add-goreleaser-homebrew skill for release automation (if Go project detected)
Error Handling
- Not a git repo: Warn the user, suggest
git init, then continue (CI workflow files do not require a git repo to create, but will not trigger without one) - No language detected: Offer a generic workflow with checkout +
make test/make linttargets - Existing CI: Ask before overwriting (covered in step 2)
- Missing Makefile: Offer to create one; if the user declines, note that CI may fail for language templates whose workflows reference
maketargets
CI Workflow Templates
./references/ci-go-cli.md-- Go CLI CI workflow./references/ci-go-library.md-- Go library CI workflow./references/ci-javascript.md-- JavaScript/TypeScript CI workflow./references/ci-python.md-- Python CI workflow./references/ci-rust.md-- Rust CI workflow./references/ci-ruby.md-- Ruby CI workflow./references/ci-shell.md-- Shell CI workflow./references/ci-zig.md-- Zig CI workflow./references/ci-zsh.md-- Zsh CI workflow./references/ci-multi-language.md-- Multi-language CI pattern
Makefile Templates
./references/makefile-go-cli.md-- Go CLI Makefile./references/makefile-go-library.md-- Go library Makefile./references/makefile-javascript.md-- JavaScript/TypeScript Makefile./references/makefile-python.md-- Python Makefile./references/makefile-rust.md-- Rust Makefile./references/makefile-ruby.md-- Ruby Makefile./references/makefile-shell.md-- Shell Makefile./references/makefile-zig.md-- Zig Makefile./references/makefile-zsh.md-- Zsh Makefile
Refresh cboone/gh-actions SHAs before scaffolding
The cboone/gh-actions reusable-workflow refs in this skill's templates are SHA-pinned with a # vX.Y.Z comment that was current when the template was authored. New releases of cboone/gh-actions rot those SHAs. Before emitting a workflow into a user's repo, refresh both the SHA and the comment to current latest:
TAG="$(gh release view --repo cboone/gh-actions --json tagName --jq '.tagName')"
SHA="$(gh api "repos/cboone/gh-actions/commits/${TAG}" --jq '.sha')"
echo "${SHA} # ${TAG}"
Replace each cboone/gh-actions/.../.yml@ # in the emitted workflow with the new SHA and tag. Dependabot in the user's repo keeps them in sync afterwards.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: cboone
- Source: cboone/agent-harness-plugins
- License: MIT
- Homepage: https://github.com/cboone/agent-harness-plugins
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.