Installs into .claude/skills of the current project.
Are you the author of Gen Goreleaser?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/sgaunet-gen-goreleaser)
---
name: gen-goreleaser
description: Generate GoReleaser configuration with multi-arch Docker builds and release automation
argument-hint: "[--force] [--minimal] [--dry-run]"
user-invocable: true
disable-model-invocation: true
allowed-tools: Read, Write, Bash(git:*), Bash(test:*), Bash(docker:*), Bash(go:*), AskUserQuestion
---
# Generate GoReleaser Configuration
Instantly create complete GoReleaser setup for Go projects with multi-architecture Docker builds, automated releases, and package distribution. This skill replaces the multi-step manual setup with a single invocation.
## Why This Skill Exists
**Problem**: Setting up GoReleaser requires:
- Creating complex YAML configuration (~300 lines)
- Designing multi-stage Dockerfiles for cross-platform builds
- Configuring non-root container users
- Understanding ldflags, build matrix, Docker buildx
- Testing across multiple architectures
A 60-90 minute process requiring deep GoReleaser knowledge.
**Solution**: One-command generation that:
- Creates production-ready `.goreleaser.yml` (316 lines)
- Includes optimized `Dockerfile` for multi-arch builds
- Sets up non-root container user configuration
- Auto-detects project structure and binary names
- Supports standard (full) and minimal modes
- Preserves all customization comments
## Content Generation Rules
**CRITICAL**: When generating any content (configuration files, Dockerfiles, commit messages, or any other output):
- **NEVER** add Claude Code attribution or co-authorship
- **NEVER** include phrases like "Generated by Claude", "Created with Claude Code", or similar
- **NEVER** add "Co-Authored-By: Claude" in commit messages or documentation
- All generated content should appear as if written by a human developer
- Focus on technical accuracy and providing working templates
## Process (7 Phases)
### Phase 1: Prerequisites Validation
**Critical checks before proceeding:**
1. **Validate Git repository:**
```bash
git rev-parse --git-dir
```
- If fails: Exit with error "Not a git repository. Run 'git init' first."
2. **Validate Go project:**
```bash
test -f go.mod
```
- If fails: Exit with error "go.mod not found. This skill is for Go projects only."
3. **Check existing GoReleaser files:**
```bash
test -f .goreleaser.yml || test -f .goreleaser.yaml
test -f Dockerfile
test -d resources/etc
```
- Store results:
- `existingConfig = true/false` (for .goreleaser.yml/yaml)
- `existingDockerfile = true/false`
- `existingResources = true/false`
- `existingFile = <filename>` if config exists
4. **Check for GoReleaser binary** (non-blocking):
```bash
command -v goreleaser
```
- If found: Check version with `goreleaser --version` and store
- If not found: Store `goreleaserNotInstalled = true` (will show warning)
5. **Check for Docker with buildx** (non-blocking):
```bash
command -v docker && docker buildx version
```
- If not found: Store `dockerNotInstalled = true` (will show warning)
6. **Verify skill assets directory:**
- Use Read tool to verify these files exist:
- `${CLAUDE_PLUGIN_ROOT}/assets/goreleaser/.goreleaser.yml`
- `${CLAUDE_PLUGIN_ROOT}/assets/goreleaser/Dockerfile`
- `${CLAUDE_PLUGIN_ROOT}/assets/goreleaser/resources/etc/passwd`
- If any fail: Exit with error "Skill assets directory incomplete at ${CLAUDE_PLUGIN_ROOT}/assets/goreleaser/. Plugin may be corrupted. Reinstall the go-specialist plugin."
### Phase 2: Argument Parsing
Parse skill arguments from `$argument` string:
**Supported flags:**
- `--force`: Skip confirmation for existing files
- `--minimal`: Generate only `.goreleaser.yml` (no Dockerfile or resources)
- `--dry-run`: Show preview without writing files
**Parsing logic:**
```
arguments = split($argument by space)
for each arg in arguments:
if arg == "--force": set forceMode = true
if arg == "--minimal": set minimalMode = true
if arg == "--dry-run": set dryRunMode = true
```
**File Selection:**
- **Standard mode** (default): All 3 files
- `.goreleaser.yml` (316 lines, ~10 KB)
- `Dockerfile` (64 lines, ~2 KB)
- `resources/etc/passwd` (3 lines, <1 KB)
- **Minimal mode** (`--minimal`): 1 file only
- `.goreleaser.yml` (316 lines, ~10 KB)
### Phase 3: Template Reading
**Read template files** from skill assets directory:
**Templates to read:**
1. **.goreleaser.yml** (always read)
- Path: `${CLAUDE_PLUGIN_ROOT}/assets/goreleaser/.goreleaser.yml`
- Expected size: ~10 KB (316 lines)
- Format: YAML with inline comments
2. **Dockerfile** (skip if `minimalMode = true`)
- Path: `${CLAUDE_PLUGIN_ROOT}/assets/goreleaser/Dockerfile`
- Expected size: ~2 KB (64 lines)
- Format: Multi-stage Docker build
3. **resources/etc/passwd** (skip if `minimalMode = true`)
- Path: `${CLAUDE_PLUGIN_ROOT}/assets/goreleaser/resources/etc/passwd`
- Expected size: <1 KB (3 lines)
- Format: Unix passwd file format
**Reading logic:**
```
For each file:
Use Read tool to read: ${CLAUDE_PLUGIN_ROOT}/assets/goreleaser/<filename>
Store content as: goreleaser_template, dockerfile_template, passwd_template
Verify: content is not empty
```
**Error handling:**
- If any file not found: Exit with error "Template file not found: <path>"
- If any file empty: Exit with error "Template file empty or corrupted: <path>"
### Phase 4: Auto-Detection & Substitution
**Detection Function Library:** Use the shared detection functions from `${CLAUDE_PLUGIN_ROOT}/assets/detection-functions.md`. Read that file to get all bash detection functions (`detect_project_name`, `detect_git_owner`, `detect_main_dir`, `detect_registry`, `detect_author`, `substitute_placeholders`).
**Detection Workflow:**
1. **Detect all values:**
```bash
PROJECT_NAME=$(detect_project_name)
OWNER=$(detect_git_owner)
REGISTRY=$(detect_registry)
MAIN_DIR=$(detect_main_dir)
AUTHOR_INFO=$(detect_author)
AUTHOR_NAME=$(echo "$AUTHOR_INFO" | cut -d'|' -f1)
AUTHOR_EMAIL=$(echo "$AUTHOR_INFO" | cut -d'|' -f2)
```
2. **Handle missing critical values** (use AskUserQuestion if empty):
- If `PROJECT_NAME` is empty: Prompt user for project name or use "app"
- If `OWNER` is empty: Prompt user for owner or preserve `[OWNER]` placeholder
- Non-critical values (AUTHOR_NAME, AUTHOR_EMAIL) can be empty strings
3. **Substitute placeholders in all templates:**
```bash
goreleaser_template=$(substitute_placeholders "$goreleaser_template" \
"$PROJECT_NAME" "$OWNER" "$REGISTRY" "$MAIN_DIR" "$AUTHOR_NAME" "$AUTHOR_EMAIL")
dockerfile_template=$(substitute_placeholders "$dockerfile_template" \
"$PROJECT_NAME" "$OWNER" "$REGISTRY" "$MAIN_DIR" "$AUTHOR_NAME" "$AUTHOR_EMAIL")
passwd_template=$(substitute_placeholders "$passwd_template" \
"$PROJECT_NAME" "$OWNER" "$REGISTRY" "$MAIN_DIR" "$AUTHOR_NAME" "$AUTHOR_EMAIL")
```
**Fallback Strategy:**
- If detection fails for critical values: Use placeholders and warn in success report
- Graceful degradation: Preserve `[PLACEHOLDER]` if user skips prompt
### Phase 5: User Confirmation
**Build preview message:**
```
π¦ GoReleaser Configuration Preview
Mode: <Standard|Minimal>
Files to be created:
<LIST FILES BASED ON MODE>
Standard mode (3 files):
.goreleaser.yml (316 lines, ~10 KB)
Dockerfile (64 lines, ~2 KB)
resources/etc/passwd (3 lines)
Minimal mode (1 file):
.goreleaser.yml (316 lines, ~10 KB)
β Auto-detected Configuration
ββββββββββββββββββββββββββββββββββββββββββββ
Project Settings:
β’ Project name: <PROJECT_NAME> (from go.mod)
β’ Binary name: <PROJECT_NAME>
β’ Main directory: <MAIN_DIR>
Repository Settings:
β’ Owner: <OWNER> (from git remote)
β’ Registry: <REGISTRY> (<GitHub Container Registry|GitLab Container Registry>)
Author Information:
β’ Name: <AUTHOR_NAME> (from git config)
β’ Email: <AUTHOR_EMAIL>
Configuration features:
β Multi-OS builds (Linux, macOS, Windows)
β Multi-arch support (amd64, arm64, arm, 386)
β Docker multi-arch manifests (linux/amd64, linux/arm64, linux/arm/v7)
β Automated changelog generation
β Archive creation with checksums
β GitHub/GitLab release integration
β Homebrew formula generation (optional)
β SBOM and attestation support
Build matrix:
β’ linux: amd64, arm64, arm, 386
β’ darwin: amd64, arm64
β’ windows: amd64, arm64, 386
Docker features (standard mode only):
β Multi-stage build (smaller images)
β Non-root user (security)
β Minimal Alpine base
β Automatic platform detection
β Distroless option available
<CONDITIONAL WARNINGS>
Next steps after generation:
1. Review and customize .goreleaser.yml
2. Update PROJECT_NAME placeholder
3. Configure Docker registry (ghcr.io, registry.gitlab.com, or docker.io)
4. Test with: goreleaser build --snapshot --clean
5. Set up CI/CD tokens for releases
```
**Conditional warnings:**
If `existingConfig = true`:
```
β οΈ WARNING: Existing GoReleaser configuration detected
File: <existingFile>
This will OVERWRITE your existing configuration.
Consider backing up before proceeding.
```
If `existingDockerfile = true` and `minimalMode = false`:
```
β οΈ WARNING: Existing Dockerfile detected
This will OVERWRITE your existing Dockerfile.
If you have custom Docker configuration, use --minimal mode or backup first.
```
If `existingResources = true` and `minimalMode = false`:
```
β οΈ WARNING: Existing resources/etc/ directory detected
passwd file will be overwritten if it exists.
```
If `goreleaserNotInstalled = true`:
```
βΉοΈ INFO: GoReleaser binary not found
Configuration will be created, but you'll need to install GoReleaser:
β’ macOS: brew install goreleaser
β’ Linux: See https://goreleaser.com/install/
After installation, verify with: goreleaser --version
```
If `dockerNotInstalled = true` and `minimalMode = false`:
```
βΉοΈ INFO: Docker or buildx not found
Dockerfile will be created, but you'll need Docker with buildx for multi-arch builds.
Install: https://docs.docker.com/buildx/working-with-buildx/
```
If `binaryName = "app"` (detection failed):
```
β οΈ WARNING: Could not detect binary name from go.mod
Using placeholder "app" - you'll need to update this in .goreleaser.yml
```
If `mainDir = "."` and multiple main.go exist:
```
βΉοΈ INFO: Multiple main.go files found
Using project root. Verify 'dir' field in .goreleaser.yml if needed.
```
**Confirmation logic:**
If `dryRunMode = true`:
```
[DRY RUN MODE - No files will be written]
```
Skip to Phase 7 (report preview only)
If `forceMode = true`:
```
[--force mode enabled, skipping confirmation]
```
Proceed to Phase 6
If any existing files and `forceMode = false`:
```
Use AskUserQuestion:
Question: "Overwrite existing GoReleaser files?"
Options:
- "Yes, overwrite all files" (proceed to Phase 6)
- "No, cancel operation" (exit with message "Operation cancelled by user")
```
If no existing files:
```
Use AskUserQuestion:
Question: "Create GoReleaser configuration <in standard/minimal mode>?"
Options:
- "Yes, create files" (proceed to Phase 6)
- "No, cancel operation" (exit with message "Operation cancelled by user")
```
### Phase 6: File Creation
**Write files based on mode:**
**Always create:**
1. **.goreleaser.yml**
```
Use Write tool:
file_path: ./.goreleaser.yml (absolute path to project root)
content: goreleaser_template (no modifications, copy as-is)
```
**Create only in standard mode** (`minimalMode = false`):
2. **Dockerfile**
```
Use Write tool:
file_path: ./Dockerfile (absolute path to project root)
content: dockerfile_template (no modifications, copy as-is)
```
3. **resources/etc/passwd**
```
Create directory first:
bash: mkdir -p resources/etc
Use Write tool:
file_path: ./resources/etc/passwd (absolute path)
content: passwd_template (no modifications, copy as-is)
```
**Writing logic:**
```
For each file:
If minimalMode = true and file not in minimal list:
Skip file
Else:
Create parent directories if needed
Use Write tool to create file
Verify write succeeded
```
**Error handling:**
- If directory creation fails: Report error with path
- If write fails: Report error with file path and error message
- If write succeeds: Continue to next file
- After all files: Proceed to Phase 7
### Phase 7: Validation & Success Report
**Post-creation validation:** confirm each written file exists and is non-zero
(`.goreleaser.yml`, plus `Dockerfile` and `resources/etc/passwd` in standard mode) and
report its line count.
**If `dryRunMode == true`:** report that nothing was written, list the files that *would* be
created with their line counts, show the detected binary name and main package, and note
that dropping `--dry-run` performs the creation.
**Otherwise report to the user** β cover these facts; no fixed layout required:
- **Files written:** each path with its line count (`.goreleaser.yml`; in standard mode also
`Dockerfile` and `resources/etc/passwd`).
- **Detected values:** project name and binary name (from go.mod), main directory, owner
(from git remote), registry with its display name, and author name/email (from git config).
- **Leftover placeholders:** if any remain, warn that the config is partial and give
`grep -r '\[.*\]' .goreleaser.yml` to find them. If none remain, say so β the config is
usable as-is with no manual editing.
- **Enabled features:** multi-OS/arch builds (9 targets), multi-arch Docker (3 platforms),
changelog generated from git log, archives (tar.gz, zip), checksums, SBOM, build
attestation, and a Homebrew formula template.
- **Next steps:** validate with `goreleaser check`; build without releasing via
`goreleaser build --snapshot --clean`; rehearse the full run with
`goreleaser release --snapshot --clean --skip=publish`; inspect `ls -la dist/`; set the CI
tokens (`GITHUB_TOKEN` and `GITLAB_TOKEN` are automatic on their platforms,
`HOMEBREW_TAP_TOKEN` only if publishing to a tap); then cut the first release with
`git tag -a v0.1.0 -m "Initial release"`, `git push origin v0.1.0` and
`goreleaser release --clean`.
- **CI integration:** `/gen-github-dir` for GitHub Actions (includes a release workflow),
`/gen-gitlab-ci` for GitLab CI (includes a release job).
- **Missing tools:** if `goreleaserNotInstalled`, remind to install it
(`brew install goreleaser` on macOS, otherwise https://goreleaser.com/install/) and verify
with `goreleaser --version` β v2.0.0+ is required. If `dockerNotInstalled` and not
`minimalMode`, remind to install Docker (https://docs.docker.com/get-docker/) with buildx
enabled (https://docs.docker.com/buildx/working-with-buildx/), verified via
`docker buildx version`.
- **Docs:** `${CLAUDE_PLUGIN_ROOT}/docs/goreleaser-reference.md` for configuration
patterns Β· `${CLAUDE_PLUGIN_ROOT}/docs/goreleaser-troubleshooting.md` Β·
https://goreleaser.com
**On failure:** report which files were written, which failed and why, and that `--force`
retries. Partial success is a warning, total failure an error β for a total failure also
name the likely causes (permissions, disk space, filesystem restrictions).
## Integration with Other Skills
This skill works seamlessly with other go-specialist skills:
**Before gen-goreleaser:**
- `/gen-linter` - Recommended to ensure code quality before releases
**After gen-goreleaser:**
- `/gen-github-dir` - Includes release workflow that uses GoReleaser
- `/gen-gitlab-ci` - Includes release job that uses GoReleaser
- `/gen-taskfiles` - Can add release tasks for local testing
**Typical workflow:**
```bash
# 1. Set up linting
/gen-linter
# 2. Configure releases
/gen-goreleaser
# 3. Test release process
goreleaser release --snapshot --clean --skip=publish
# 4. Set up CI/CD
/gen-github-dir # or /gen-gitlab-ci
# 5. Create first release
git tag -a v0.1.0 -m "Initial release"
git push origin v0.1.0
```
## Mode Comparison
### Standard Mode (Default)
**Use when:**
- Publishing Docker images
- Need multi-architecture container support
- Want complete release automation
- Deploying to Kubernetes or container platforms
**Creates:**
- `.goreleaser.yml` - Full configuration
- `Dockerfile` - Multi-stage optimized build
- `resources/etc/passwd` - Non-root user config
**Benefits:**
- Complete Docker integration
- Security-hardened containers
- Minimal image size
- Multi-platform support
### Minimal Mode (`--minimal`)
**Use when:**
- Binary-only releases (no containers)
- Custom Docker setup exists
- Want minimal configuration
- Testing GoReleaser for first time
**Creates:**
- `.goreleaser.yml` only
**Benefits:**
- Simpler setup
- No Docker dependencies
- Easy customization
- Faster generation
## Best Practices
**Configuration maintenance:**
- Keep GoReleaser version updated (v2.0.0+)
- Test with `--snapshot` before tagging
- Review changelog generation settings
- Verify build matrix for target platforms
**Release workflow:**
- Use semantic versioning (v1.2.3)
- Write conventional commits for changelog
- Tag releases from stable branches
- Test multi-arch builds locally when possible
**Docker best practices:**
- Use specific base image versions
- Minimize layer count
- Run as non-root user
- Scan images for vulnerabilities
**CI/CD integration:**
- Store tokens in CI/CD secrets
- Run release only on tags
- Cache Docker layers
- Verify checksums in release artifacts
**Security considerations:**
- Sign releases with GPG/cosign
- Generate SBOMs for compliance
- Use attestation for supply chain security
- Keep base images updated
## Limitations & Caveats
**Project requirements:**
- Go modules required (go.mod must exist)
- Git repository required
- Semantic version tags expected (v1.2.3)
**Docker limitations:**
- Requires Docker with buildx for multi-arch
- Registry credentials needed for pushing
- Build times increase with multiple platforms
- ARM builds may need QEMU on x86 hosts
**Platform support:**
- CGO disabled by default (pure Go only)
- Windows ARM support limited
- Some platforms may need custom ldflags
**Configuration complexity:**
- Template has opinionated defaults
- May need customization for monorepos
- Homebrew tap requires separate repository
## Error Recovery
**If goreleaser check fails:**
1. Verify YAML syntax: `yamllint .goreleaser.yml`
2. Check for required fields (project_name, builds)
3. Validate file paths in configuration
4. Review error message for specific issues
**If builds fail:**
1. Check main package location: `go build <mainDir>`
2. Verify Go module is valid: `go mod tidy`
3. Test individual platforms: `goreleaser build --snapshot --single-target`
4. Review ldflags for syntax errors
**If Docker build fails:**
1. Test Dockerfile locally: `docker build -t test .`
2. Verify buildx is available: `docker buildx ls`
3. Check registry authentication
4. Try building for single platform first
**If release fails:**
1. Verify Git tag exists: `git tag -l`
2. Check token permissions (GitHub/GitLab)
3. Review network connectivity
4. Check for existing release with same tag
## Additional Resources
**Skill documentation:**
- Configuration patterns: `${CLAUDE_PLUGIN_ROOT}/docs/goreleaser-reference.md`
- Troubleshooting guide: `${CLAUDE_PLUGIN_ROOT}/docs/goreleaser-troubleshooting.md`
**Official resources:**
- GoReleaser docs: https://goreleaser.com
- Configuration reference: https://goreleaser.com/customization/
- Docker buildx: https://docs.docker.com/buildx/working-with-buildx/
- Multi-arch images: https://www.docker.com/blog/multi-arch-images/
**Related skills:**
- `/gen-github-dir` - GitHub Actions with release workflow
- `/gen-gitlab-ci` - GitLab CI with release job
- `/gen-linter` - Code quality before releases
**Community resources:**
- Example configs: https://github.com/goreleaser/goreleaser/tree/main/.github/workflows
- Best practices: https://goreleaser.com/cookbooks/
- GitHub discussions: https://github.com/goreleaser/goreleaser/discussions