Skip to content
Back to skills

Gen Goreleaser

BSecurity

Generate GoReleaser configuration with multi-arch Docker builds and release automation

  • 16 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 25, 2026
developmentgobashdockerkubernetestestinggitci/cdsecuritydocumentation

Works with

  • claude code

Security analysis

B75/100
  • criticalAccesses sensitive system or user directories

Pro shows the line behind each finding and how to fix it

Scanned September 25, 2026

npx -y skills add sgaunet/claude-plugins --skill gen-goreleaser --agent claude-code

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.

Security grade badge for Gen Goreleaser
[![Security: B β€” Skills Directory](https://www.skillsdirectory.com/api/skills/sgaunet-gen-goreleaser/badge)](https://www.skillsdirectory.com/skills/sgaunet-gen-goreleaser)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.