Skip to content
Back to skills

Gen Forgejo Dir

ASecurity

Generate complete .forgejo/workflows directory with Forgejo Actions workflows (test, lint, release) for Go projects

  • 16 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 25, 2026
developmentgobashdockergitapici/cddocumentation

Works with

  • claude code
  • cli
  • api

Security analysis

A100/100

Scanned September 25, 2026

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

Installs into .claude/skills of the current project.

Are you the author of Gen Forgejo Dir?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Gen Forgejo Dir
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/sgaunet-gen-forgejo-dir/badge)](https://www.skillsdirectory.com/skills/sgaunet-gen-forgejo-dir)

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-forgejo-dir
description: Generate complete .forgejo/workflows directory with Forgejo Actions workflows (test, lint, release) for Go projects
argument-hint: "[--force] [--minimal] [--dry-run]"
user-invocable: true
disable-model-invocation: true
allowed-tools: Read, Write, Bash(git:*), Bash(test:*), Bash(fgj:*), AskUserQuestion
---

# Generate .forgejo Directory

Instantly create a complete `.forgejo/workflows` directory structure for Go projects with production-ready, **mise-based** Forgejo Actions workflows (linting, coverage, snapshot builds, releases).

Forgejo Actions reuses **GitHub-Actions-compatible workflow syntax**, so the workflow content is identical to what `/gen-github-dir` produces. The key differences are the directory location (`.forgejo/workflows/` instead of `.github/workflows/`), the `runs-on` runner label, and the action/registry source assumptions described below.

Like the GitHub variant, the workflows install tooling via `jdx/mise-action@v3` and run `task …`, so CI uses the exact tool versions pinned in `mise.toml` (created at the repo root if missing). This also **shrinks the set of GitHub actions that must be mirrored** on your instance to just `actions/checkout` and `jdx/mise-action`.

## Why This Skill Exists

**Problem**: Setting up CI/CD for Go projects on a Forgejo instance requires manually creating multiple workflow files, understanding that Forgejo Actions mirrors GitHub Actions syntax but lives under a different directory, and wiring up runner labels - a 30-60 minute process.

**Solution**: One-command generation that:
- Creates a complete `.forgejo/workflows` directory structure
- Includes comprehensive workflows: linting, coverage, snapshot builds, releases
- Targets a Forgejo Actions runner label (not `ubuntu-latest`)
- Preserves all customization comments for user control

## Forgejo Actions Assumptions

This skill makes the following assumptions about your Forgejo instance. Review them before running:

1. **Runner label** — Workflows are generated with `runs-on: docker` (a common default label for the official Forgejo Actions runner). You must have at least one registered Forgejo Actions runner that advertises this label. Manage runners with the Forgejo CLI:
   ```bash
   fgj actions runner list        # List registered runners and their labels
   fgj actions runner register    # Register a new runner
   ```
   If your runner uses a different label (e.g. `self-hosted`, `ubuntu-latest`, or a custom label), edit `runs-on:` in the generated files or re-run after adjusting your runner registration. Without a matching registered runner, workflows will queue forever.

2. **Action source / GitHub mirror** — Because tooling is installed via mise, the workflows only reference **two** GitHub actions: `actions/checkout` and `jdx/mise-action`. Forgejo pulls actions from a **configurable registry**; on instances configured with a GitHub Actions proxy/mirror (the common default, e.g. `https://data.forgejo.org` or a `code.forgejo.org` mirror), these references resolve transparently. If your instance is not configured to mirror GitHub actions, replace these two `uses:` references with mirrored equivalents available on your instance. (The optional docker-publishing blocks add `docker/setup-qemu-action` / `docker/login-action` only if you uncomment them.)

3. **Container/package registry** — Docker image publishing is **off by default** (mirrors the binary-only baseline). To publish images, uncomment the docker tools in `mise.toml` and the QEMU + registry-login block in the release/snapshot workflows. On a Forgejo instance the registry shares the instance host (e.g. `git.sylvlab.fr`); set the login `registry:` accordingly (detected via the shared `detect_registry()` helper).

4. **Release token & SCM (goreleaser)** — This is the one place the shared GitHub release template is *not* drop-in correct for Forgejo. The shared `release.yml` exports only `GITHUB_TOKEN` and the GitHub templates assume goreleaser publishes to github.com. Publishing a release to your Forgejo/Gitea instance instead requires **both**:
   - A **`gitea_urls:` block in `.goreleaser.yml`** pointing goreleaser at your instance API (e.g. `api: https://git.sylvlab.fr/api/v1`, `download: https://git.sylvlab.fr`). This switches goreleaser to its **gitea** release publisher. Generate/edit it with `/gen-goreleaser`.
   - The release job to export **`GITEA_TOKEN`** — goreleaser's gitea publisher reads this variable, not `GITHUB_TOKEN`. This skill adds `GITEA_TOKEN` to the generated `.forgejo/workflows/release.yml` (Phase 3.5), defaulting it to the job token Forgejo auto-provides (exposed as `secrets.GITHUB_TOKEN`). For broader scope (cross-repo pushes, package registry), create a dedicated `GITEA_TOKEN` repository secret and reference it instead.

   Without both, the release job either targets github.com or fails to authenticate against your instance. `snapshot.yml` is unaffected — it runs goreleaser in `--snapshot` mode and never publishes.

## Content Generation Rules

**CRITICAL**: When generating any content (workflow files, 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 (6 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 .forgejo directory:**
   ```bash
   test -d .forgejo
   ```
   - If exists: Store `existingForgejoDir = true`
   - If not exists: Store `existingForgejoDir = false`

4. **Verify skill assets directory:**
   - Use Read tool to verify `${CLAUDE_PLUGIN_ROOT}/assets/github-workflows/workflows/linter.yml` exists
     (Forgejo reuses the GitHub-Actions-compatible workflow templates.)
   - Use Read tool to verify `${CLAUDE_PLUGIN_ROOT}/assets/mise/mise.toml` exists
   - If either fails: Exit with error "Skill assets directory not found at ${CLAUDE_PLUGIN_ROOT}/assets/. Plugin may be corrupted. Reinstall the go-specialist plugin."

5. **Check existing mise.toml:**
   ```bash
   test -f mise.toml
   ```
   - Store `existingMise = true|false`. The workflows depend on `mise.toml`; if it
     is missing this skill creates one (Phase 3.5). An existing one is preserved.

### Phase 2: Argument Parsing

Parse skill arguments from `$argument` string:

**Supported flags:**
- `--force`: Skip confirmation for existing .forgejo directory
- `--minimal`: Generate only essential files (2 files: workflows/linter.yml, workflows/release.yml)
- `--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 4 workflow files
  - workflows/linter.yml
  - workflows/coverage.yml
  - workflows/snapshot.yml
  - workflows/release.yml

- **Minimal mode** (`--minimal`): 2 essential files
  - workflows/linter.yml
  - workflows/release.yml

> Note: Unlike `/gen-github-dir`, this skill does NOT generate `FUNDING.yml` or `dependabot.yml`. Forgejo does not use GitHub Sponsors funding files, and dependency updates on Forgejo are handled by the instance's own mechanisms (e.g. Renovate) rather than `dependabot.yml`.

### Phase 3: Template Reading

**Read all template files** from the shared GitHub-Actions-compatible skill assets directory:

**Files to read:**

1. **workflows/linter.yml**
   - Path: `${CLAUDE_PLUGIN_ROOT}/assets/github-workflows/workflows/linter.yml`
   - Target: `.forgejo/workflows/linter.yml`

2. **workflows/coverage.yml** [Skip if minimal mode]
   - Path: `${CLAUDE_PLUGIN_ROOT}/assets/github-workflows/workflows/coverage.yml`
   - Target: `.forgejo/workflows/coverage.yml`

3. **workflows/snapshot.yml** [Skip if minimal mode]
   - Path: `${CLAUDE_PLUGIN_ROOT}/assets/github-workflows/workflows/snapshot.yml`
   - Target: `.forgejo/workflows/snapshot.yml`

4. **workflows/release.yml**
   - Path: `${CLAUDE_PLUGIN_ROOT}/assets/github-workflows/workflows/release.yml`
   - Target: `.forgejo/workflows/release.yml`

5. **mise.toml** [Only if `existingMise == false`]
   - Path: `${CLAUDE_PLUGIN_ROOT}/assets/mise/mise.toml`
   - Target: `mise.toml` (repo root)

**Template handling:**
- Store content in memory for Phase 3.5 substitution
- The workflow templates are **static** apart from the `runs-on` runner label —
  tool versioning lives in `mise.toml`.
- Preserve all `# CUSTOMIZE:` comments

**Error handling:**
- If any Read fails: Exit with error "Failed to read template file: {filename}. Plugin may be corrupted."

### Phase 3.5: Auto-Detection & Substitution

**Detection Function Library:** Use the shared detection functions from `${CLAUDE_PLUGIN_ROOT}/assets/detection-functions.md`. Read that file to get the bash detection functions (`detect_registry`, `detect_go_version`, `detect_golangci_lint_version`, `detect_goreleaser_version`, `strip_leading_v`, `substitute_version_placeholders`).

**Detection Workflow:**

1. **Detect Forgejo runner label (best-effort):**
   - Prefer the Forgejo CLI when available to pick a real runner label instead of the `docker` default:
     ```bash
     # Best-effort: pick the first label advertised by a registered runner
     FORGEJO_RUNNER_LABEL=$(fgj actions runner list 2>/dev/null | awk 'NR>1 {print $NF; exit}')
     ```
   - If `fgj` is not installed or returns nothing, fall back to the default label `docker`.
   - `FORGEJO_RUNNER_LABEL=${FORGEJO_RUNNER_LABEL:-docker}`

2. **Substitute the runner label (`runs-on`):**
   The shared GitHub templates use `runs-on: ubuntu-latest`. Rewrite this to the Forgejo runner label in every workflow template:
   ```bash
   workflow_template=$(echo "$workflow_template" | sed "s|runs-on: ubuntu-latest|runs-on: ${FORGEJO_RUNNER_LABEL}|g")
   ```
   - `runs-on` is the only substitution **every** workflow needs; `release.yml`
     additionally gets the release-token injection below.

3. **Inject the Forgejo release token (`release.yml` only):**
   The shared `release.yml` job env exports only `GITHUB_TOKEN`, which is correct
   for github.com. For a Forgejo/Gitea release, goreleaser's **gitea** publisher
   authenticates with `GITEA_TOKEN` (and needs a `gitea_urls:` block in
   `.goreleaser.yml`). Add `GITEA_TOKEN` to the release job env in the generated
   `.forgejo/workflows/release.yml`. This rewrites only the Forgejo copy held in
   memory — the shared GitHub asset is never modified:
   ```bash
   # Applies to the release.yml content only; snapshot.yml never publishes.
   release_template=$(printf '%s' "$release_template" | sed \
     's|^\( *\)GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}$|\1# Forgejo/Gitea release: goreleaser authenticates with GITEA_TOKEN (needs gitea_urls: in .goreleaser.yml).\n\1# Defaults to the job token Forgejo auto-provides (exposed as secrets.GITHUB_TOKEN);\n\1# for broader scope, create a GITEA_TOKEN repo secret and reference it here.\n\1GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\1GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}|')
   ```
   - Apply to `release.yml` only — `snapshot.yml` runs goreleaser in `--snapshot`
     mode and needs no release token, so leave it untouched.
   - Pair this with a `gitea_urls:` block in `.goreleaser.yml` (see `/gen-goreleaser`),
     otherwise goreleaser still defaults to publishing on github.com.

4. **Ensure `mise.toml` exists (create if missing):**
   The workflows install tools from `mise.toml`. If the repo has no `mise.toml`,
   create one from the asset with detected versions:
   ```bash
   if [[ "$existingMise" != "true" ]]; then
       GO_VERSION=$(detect_go_version)
       GOLANGCI_LINT_VERSION=$(detect_golangci_lint_version)   # gh release view (external GitHub repo)
       GORELEASER_VERSION=$(detect_goreleaser_version)
       GOLANGCI_LINT_VERSION_BARE=$(strip_leading_v "${GOLANGCI_LINT_VERSION:-v2.2.2}")

       mise_template=$(substitute_version_placeholders "$mise_template" \
           "GO_VERSION=${GO_VERSION:-1.25}" \
           "GOLANGCI_LINT_VERSION_BARE=${GOLANGCI_LINT_VERSION_BARE:-2.2.2}" \
           "GORELEASER_VERSION=${GORELEASER_VERSION:-v2.12.0}")
       # Written in Phase 5.
   fi
   ```
   - If `existingMise == true`: do NOT modify the existing `mise.toml`; note it in the report.
   - golangci-lint/goreleaser/go are external GitHub-hosted tools; keep the
     GitHub-based version detection (Forgejo has no equivalent for third-party repos).

5. **Detect container registry (optional docker block):**
   ```bash
   REGISTRY=$(detect_registry)   # On a Forgejo instance like git.sylvlab.fr → git.sylvlab.fr
   ```
   - Only relevant if you enable the optional docker-publishing block: on a Forgejo
     instance the registry shares the instance host; set the login `registry:` value
     accordingly.

6. **Handle missing values:**
   - If `FORGEJO_RUNNER_LABEL` could not be detected: Use `docker` and note it in the report so the user can verify against `fgj actions runner list`.
   - Non-blocking: User can still create files and edit `runs-on:` manually later.

### Phase 4: User Confirmation

**Build preview summary:**

```
Files to be created:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[If standard mode:]
✅ .forgejo/workflows/linter.yml
✅ .forgejo/workflows/coverage.yml
✅ .forgejo/workflows/snapshot.yml
✅ .forgejo/workflows/release.yml

Total: 4 files

[If minimal mode:]
✅ .forgejo/workflows/linter.yml
✅ .forgejo/workflows/release.yml

Total: 2 files

[If existingMise == false:]
✅ mise.toml (created — pins go/task/golangci-lint/goreleaser for dev + CI)
[If existingMise == true:]
ℹ️  mise.toml already exists — preserved (workflows will use it as-is)

✅ Auto-detected Configuration
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Forgejo Settings:
  • Runner label: <FORGEJO_RUNNER_LABEL> (from `fgj actions runner list`, or default `docker`)
  • Tool versions (mise.toml): Go <GO_VERSION>, golangci-lint <GOLANGCI_LINT_VERSION_BARE>, goreleaser <GORELEASER_VERSION>
  • Container registry: <REGISTRY> (only used by the optional docker block)

[If existingForgejoDir == true:]
⚠️  WARNING: .forgejo directory already exists
[List existing files that will be overwritten:]
- .forgejo/workflows/linter.yml (will be overwritten)
- .forgejo/workflows/release.yml (will be overwritten)
```

**Dry run mode:**
If `dryRunMode == true`:
- Show preview summary above
- Show first 20 lines of each workflow file
- Display next steps guide
- Exit without creating files

**Confirmation logic:**

1. **If `--force` flag provided:** Skip confirmation, proceed to Phase 5

2. **If existing .forgejo without `--force`:**
   ```
   Use AskUserQuestion:
   Question: ".forgejo directory already exists. Overwrite existing workflow files?"
   Options:
   1. "Yes, overwrite files" [Recommended if upgrading workflows]
   2. "Show full preview first"
   3. "Cancel"

   If option 2: Display full content preview, then re-ask confirmation
   If option 3: Exit gracefully
   ```

3. **If new .forgejo directory:**
   ```
   Use AskUserQuestion:
   Question: "Create .forgejo directory with [N] files?"
   Options:
   1. "Yes, create files"
   2. "Show preview first"
   3. "Cancel"
   ```

### Phase 5: File Creation

**Directory creation:**

1. Create `.forgejo/workflows/` directory:
   ```bash
   mkdir -p .forgejo/workflows
   ```

**File writing sequence:**

1. `mise.toml` [Only if `existingMise == false`] — repo root, version-substituted
2. `.forgejo/workflows/linter.yml`
3. `.forgejo/workflows/coverage.yml` [Skip if minimal mode]
4. `.forgejo/workflows/snapshot.yml` [Skip if minimal mode]
5. `.forgejo/workflows/release.yml`

**For each file:**
- Use Write tool with full file path
- Write content from Phase 3.5 templates (with substitutions applied)
- Track success/failure status
- Continue with remaining files if one fails (partial success acceptable)

**Error handling:**
- If directory creation fails: Exit with error
- If individual file write fails: Log error, continue with next file
- If all writes fail: Report failure with details
- If partial success: Report which files succeeded/failed

**Track results:**
```
successfulFiles = []
failedFiles = []

for each file:
  try write:
    if success: add to successfulFiles
    if failure: add to failedFiles
```

### Phase 6: Validation & Success Report

**Post-creation validation:** for each file in `successfulFiles`, confirm it exists
(e.g. `test -f .forgejo/workflows/linter.yml`) and is non-zero; move any failure to
`failedFiles`.

**Report to the user** — cover these facts; no fixed layout required:

- **Files written:** each path with a total count — `.forgejo/workflows/linter.yml` and
  `.forgejo/workflows/release.yml`, plus `.forgejo/workflows/coverage.yml` and
  `.forgejo/workflows/snapshot.yml` in standard mode. Mark `mise.toml` as created vs.
  preserved.
- **Detected values:** the runner label `<FORGEJO_RUNNER_LABEL>`, and — if `mise.toml` was
  created — the pinned Go, golangci-lint and goreleaser versions.
- **Verify the runner label:** `fgj actions runner list` should show a registered runner
  advertising `<FORGEJO_RUNNER_LABEL>`. If none does, register one with
  `fgj actions runner register`, or edit `runs-on:` in `.forgejo/workflows/*.yml` to match
  an existing label.
- **Confirm action mirroring:** the workflows reference only `actions/checkout` and
  `jdx/mise-action`, which require the instance to mirror or proxy GitHub actions. If it
  does not, replace those two `uses:` references with mirrored equivalents.
- **Tool versions:** pinned in `mise.toml`, not the workflow files — editing it changes both
  local (`mise install`) and CI versions.
- **Release publisher (release.yml + .goreleaser.yml):** `release.yml` exports `GITEA_TOKEN`,
  defaulting to the job token Forgejo auto-provides (`secrets.GITHUB_TOKEN`); for broader
  scope, create a `GITEA_TOKEN` repo-level secret and reference it there. Add a
  `gitea_urls:` block (the instance's api/download URLs) to `.goreleaser.yml` so goreleaser
  publishes to Forgejo rather than github.com — generate or edit that file with
  `/gen-goreleaser`.
- **Optional customizations:** to publish Docker images, uncomment the docker tools
  (buildx, docker-cli) in `mise.toml` and the QEMU + registry-login block in `snapshot.yml`
  and `release.yml`, setting the login registry to `<REGISTRY>`. The coverage threshold is
  `limit-coverage: 70` in `.forgejo/workflows/coverage.yml`.
- **Next steps:** review the workflow files, confirm a runner is registered and online
  (`fgj actions runner list`), then `git add .forgejo/ mise.toml` and
  `git commit -m "ci: add mise-based Forgejo Actions workflows"`, `git push origin main`,
  and check the repository's Actions tab — the workflows should run on the next push if a
  runner is online.

**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).

## Arguments

Arguments are parsed from the `argument` string parameter:

- **`--force`**: Skip confirmation prompt and overwrite existing files
  - Use when: Upgrading existing workflows to latest templates
  - Behavior: Files are overwritten directly (no backups)

- **`--minimal`**: Generate only 2 essential files
  - Includes: workflows/linter.yml, workflows/release.yml
  - Excludes: workflows/coverage.yml, workflows/snapshot.yml
  - Use when: Quick CI/CD setup without advanced features

- **`--dry-run`**: Preview files without writing to disk
  - Shows: File list, preview of content
  - Writes: Nothing
  - Use when: Reviewing what will be created before committing

**Parsing example:**
```
argument = "--force --minimal"
Split by space, check for each flag:
- forceMode = true
- minimalMode = true
- dryRunMode = false
```

## Error Handling

### Critical Errors (Exit Immediately)

**Not a Git repository:**
```
❌ Error: Not a git repository

This skill requires a Git repository. Initialize one:
  git init
  git add .
  git commit -m "Initial commit"
```

**Not a Go project:**
```
❌ Error: go.mod not found

This skill is for Go projects only. Initialize a Go module:
  go mod init git.sylvlab.fr/username/project
```

**Skill assets missing:**
```
❌ Error: Skill assets directory not found

The go-specialist plugin may be corrupted. Try:
1. Reinstalling the plugin
2. Updating Claude Code to latest version
3. Reporting issue at: https://github.com/sgaunet/claude-plugins/issues
```

### Warning Errors (Continue with Others)

**Existing .forgejo directory:**
- Without `--force`: Request user confirmation
- With `--force`: Overwrite silently

**Individual file write failure:**
- Log error message
- Continue with remaining files
- Report partial success at end

**Runner label not detectable (`fgj` unavailable):**
- Fall back to `docker`
- Note in final report so the user verifies against `fgj actions runner list`

### Recovery Actions

**If mkdir fails:**
```
❌ Error: Failed to create .forgejo directory

Check:
1. Current directory is writable
2. Sufficient disk space
3. No existing .forgejo file (not directory) blocking creation

Current permissions: [show with ls -ld .]
```

**If all writes fail:**
```
❌ Error: Failed to write any workflow files

This may indicate:
1. Permission issues in .forgejo directory
2. Disk full
3. File system mounted read-only

Check disk space: df -h .
Check permissions: ls -la .forgejo/
```

## File Mapping

Complete mapping from skill assets to target locations. Forgejo reuses the GitHub-Actions-compatible templates; only the target directory and the `runs-on` label differ.

| Source Path | Target (Relative to CWD) | Mode |
|-------------|--------------------------|------|
| `${CLAUDE_PLUGIN_ROOT}/assets/mise/mise.toml` | `mise.toml` | Create-if-missing |
| `${CLAUDE_PLUGIN_ROOT}/assets/github-workflows/workflows/linter.yml` | `.forgejo/workflows/linter.yml` | All |
| `${CLAUDE_PLUGIN_ROOT}/assets/github-workflows/workflows/coverage.yml` | `.forgejo/workflows/coverage.yml` | Standard |
| `${CLAUDE_PLUGIN_ROOT}/assets/github-workflows/workflows/snapshot.yml` | `.forgejo/workflows/snapshot.yml` | Standard |
| `${CLAUDE_PLUGIN_ROOT}/assets/github-workflows/workflows/release.yml` | `.forgejo/workflows/release.yml` | All |

**Mode Legend:**
- **All**: Created in both standard and minimal modes
- **Standard**: Only created in standard mode (skipped in minimal)
- **Create-if-missing**: Written only when the repo has no `mise.toml`; an existing one is preserved

## Difference vs /gen-github-dir

| Aspect | /gen-github-dir | /gen-forgejo-dir |
|--------|-----------------|------------------|
| Directory | `.github/workflows/` | `.forgejo/workflows/` |
| `runs-on` | `ubuntu-latest` | Forgejo runner label (`docker` default, or detected via `fgj`) |
| Actions source | GitHub Marketplace | Configurable registry (assumes GitHub action mirror/proxy) |
| Actions referenced | `actions/checkout`, `jdx/mise-action` | Same two (fewer to mirror) |
| Tool install | mise (`mise.toml`) | mise (`mise.toml`) |
| Runner | GitHub-hosted | Self-hosted Forgejo Actions runner (`fgj actions runner register`) |
| Registry (optional docker) | `ghcr.io` | Instance host (e.g. `git.sylvlab.fr`) |
| Release publishing | goreleaser → github.com via `GITHUB_TOKEN` | goreleaser → instance via `GITEA_TOKEN` + `gitea_urls:` in `.goreleaser.yml` |
| FUNDING.yml | Yes (GitHub Sponsors) | No (not applicable) |
| dependabot.yml | Yes | No (Forgejo handles deps differently, e.g. Renovate) |
| Workflow YAML | GitHub Actions syntax | Same syntax (Forgejo Actions is GitHub-compatible) |

## Integration with Other Skills

**Works with:**
- `/commit`: Commit generated .forgejo directory
- `/gen-goreleaser`: Generate .goreleaser.yml config (required for release/snapshot workflows)
- `/gen-linter`: Generate .golangci.yml config (required for linter workflow)
- `/gen-taskfiles`: Generate Taskfile.yml with `lint`, `snapshot`, `release` tasks

**Typical Workflow:**
```bash
# 1. Generate dev tooling first (Taskfile.yml + mise.toml)
/gen-taskfiles

# 2. Generate .forgejo directory (reuses mise.toml; creates it if you skipped step 1)
/gen-forgejo-dir

# 3. Generate supporting configs
/gen-linter          # Creates .golangci.yml
/gen-goreleaser      # Creates .goreleaser.yml

# 4. Ensure a runner is registered
fgj actions runner list   # or: fgj actions runner register

# 5. Commit everything
git add .forgejo/ mise.toml Taskfile*.yml .golangci.yml .goreleaser.yml
git commit -m "ci: add mise-based Forgejo Actions workflows and supporting configs"

# 6. Push and verify
git push origin main
# Check: https://git.sylvlab.fr/username/repo/actions
```

## Prerequisites for Workflows

**Required for workflows to function:**

1. **A registered Forgejo Actions runner** advertising the `runs-on` label used in the workflows:
   ```bash
   fgj actions runner list        # Inspect runners and labels
   fgj actions runner register    # Register a new runner
   ```

2. **GitHub action mirroring enabled** on the instance so `uses: actions/checkout` and `uses: jdx/mise-action` resolve.

3. **mise.toml** (auto-created by this skill if missing) — pins the tool versions installed by `jdx/mise-action`. Managed canonically by `/gen-taskfiles`.

4. **Taskfile.yml** with required tasks (`lint`, `snapshot`, `release`):
   ```yaml
   version: '3'
   tasks:
     lint:
       cmds: [golangci-lint run ./...]
     snapshot:
       cmds: [goreleaser release --snapshot --clean]
     release:
       cmds: [goreleaser release --clean]
   ```
   - Generate with `/gen-taskfiles` (also emits mise.toml).

5. **.golangci.yml** configuration — generate with `/gen-linter` (golangci-lint itself comes from mise.toml).

6. **.goreleaser.yml** configuration — generate with `/gen-goreleaser` (required for snapshot.yml and release.yml). To publish releases to your Forgejo/Gitea instance (not github.com) it must include a `gitea_urls:` block, and the release job must export `GITEA_TOKEN` (this skill adds it to `release.yml`, defaulting to the auto-provided job token).

## Template Customization Points

All template files include `# CUSTOMIZE:` comments marking required changes:

**mise.toml:**
- Tool versions (`go`, `golangci-lint`, `goreleaser`) → adjust as needed (used by dev + CI)
- Docker tools (`buildx`, `docker-cli`) → uncomment if publishing images

**workflows/*.yml:**
- `runs-on: <label>` → Match a label advertised by a registered Forgejo runner
- Tag patterns in release.yml → Adjust semver format if needed
- `GITEA_TOKEN` in release.yml → defaults to the auto-provided job token; swap to a `GITEA_TOKEN` repo secret for broader scope (requires `gitea_urls:` in `.goreleaser.yml`)
- Optional docker block in snapshot.yml / release.yml → uncomment for image publishing

**coverage.yml:**
- `limit-coverage: "70"` → Adjust coverage threshold
- `sed -i '/cmd/d'` → Remove if including cmd package in coverage

## Best Practices

**Before running this skill:**
1. Ensure git repository initialized
2. Have go.mod configured
3. Confirm a Forgejo Actions runner is registered (`fgj actions runner list`)

**After generation:**
1. Review all `# CUSTOMIZE:` comments in workflow files
2. Verify the `runs-on` label matches a registered runner
3. Create required supporting files (Taskfile.yml, .goreleaser.yml, .golangci.yml)
4. Commit with a meaningful message
5. Monitor first workflow runs in the Forgejo Actions tab

## Limitations

**This skill does NOT:**
- Generate Taskfile.yml (use `/gen-taskfiles` or create manually)
- Generate .goreleaser.yml (use `/gen-goreleaser`)
- Generate .golangci.yml (use `/gen-linter`)
- Register or configure Forgejo Actions runners (use `fgj actions runner ...`)
- Configure GitHub action mirroring on the instance (instance-admin task)
- Validate that workflows will work (requires proper runner + mirror setup)

**Scope boundaries:**
- Only handles the `.forgejo/workflows/` directory structure
- Reuses opinionated GitHub-Actions-compatible templates
- Assumes standard Go project structure and an instance with action mirroring

## Examples

```bash
# Standard generation (4 workflow files)
/gen-forgejo-dir

# Minimal setup (2 essential files)
/gen-forgejo-dir --minimal

# Preview before creating
/gen-forgejo-dir --dry-run

# Overwrite existing workflows
/gen-forgejo-dir --force

# Minimal with force (quick upgrade)
/gen-forgejo-dir --minimal --force
```

## Output Summary

**Standard mode (default):**
- 4 workflow files + mise.toml (if missing)
- Comprehensive, mise-based CI/CD pipeline (lint, coverage, snapshot, release)

**Minimal mode (`--minimal`):**
- 2 workflow files + mise.toml (if missing)
- Essential linting + releases

**Dry run mode (`--dry-run`):**
- 0 files created
- Preview shown

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.