|
|
||
|---|---|---|
| .. | ||
| caller-npm.yml | ||
| caller-pypi.yml | ||
| ci-publish-separate.yml | ||
| publish-auto-detect.yml | ||
| publish-config.yml | ||
| publish-npm.yml | ||
| publish-pypi.yml | ||
| README.md | ||
| workflow-build.yml | ||
| workflow-no-build.yml | ||
Forgejo Actions Workflow Templates
Standardized workflow templates for automated package publishing in the @packages workspace.
Available Templates
1. publish-npm.yml - TypeScript/npm Packages (Standard)
Use for: Most TypeScript packages with build steps
Features:
- Configuration-driven (reads
package.json._metadata) - Workspace dependency transformation (
workspace:*→*) - Version existence check (prevents redundant publishes)
- Graceful error handling (missing scripts don't break CI)
- Single job for fast CI (< 5 minutes typical)
When to use:
- ✅ TypeScript packages with build step
- ✅ Packages with
tsup,tsc, or similar build tools - ✅ Standard npm packages
Setup:
# Copy template
cp scripts/forgejo/templates/publish-npm.yml <package>/.forgejo/workflows/publish.yml
# Ensure package.json has metadata
{
"_": {
"registry": "forgejo",
"publish": true,
"build": true
}
}
# Commit and push
cd <package>
git add .forgejo/workflows/publish.yml
git commit -m "ci: add Forgejo Actions publish workflow"
git push
2. publish-pypi.yml - Python/PyPI Packages
Use for: Python packages published to Forgejo PyPI registry
Features:
- Pre-publish version check (using
pip index versions) - Path-based triggers (only runs on
pyproject.tomlorsrc/**changes) - Optional testing with
pytest(non-blocking) - Graceful 409 Conflict handling (version already published)
- Python 3.12 environment
When to use:
- ✅ Python packages with
pyproject.toml - ✅ Python packages with
setup.py - ✅ Any Python library or CLI tool
Setup:
# Copy template
cp scripts/forgejo/templates/publish-pypi.yml <package>/.forgejo/workflows/pypi-publish.yml
# Ensure pyproject.toml has metadata
[project]
name = "package-name"
version = "1.0.0"
# Commit and push
cd <package>
git add .forgejo/workflows/pypi-publish.yml
git commit -m "ci: add Forgejo Actions PyPI publish workflow"
git push
3. publish-config.yml - Configuration Packages
Use for: Config-only packages (no build required)
Features:
- JSON/YAML validation
- No build step (publishes source directly)
- Fast CI (< 1 minute typical)
- Version existence check
When to use:
- ✅ ESLint configurations (
@eslint/*) - ✅ TypeScript configurations (
@typescript/*) - ✅ Prettier configurations
- ✅ Any package where source === dist
Setup:
# Copy template
cp scripts/forgejo/templates/publish-config.yml <package>/.forgejo/workflows/publish.yml
# Ensure package.json has metadata (note: build: false)
{
"_": {
"registry": "forgejo",
"publish": true,
"build": false
}
}
# Commit and push
cd <package>
git add .forgejo/workflows/publish.yml
git commit -m "ci: add Forgejo Actions publish workflow"
git push
4. ci-publish-separate.yml - Advanced CI/CD (Multi-Job)
Use for: High-impact packages requiring thorough validation
Features:
- Separate
validateandpublishjobs - Validate runs on all PRs and pushes
- Publish only runs on main branch after validation passes
- More thorough testing (typecheck + test + build)
- Explicit publish gate
When to use:
- ✅ High-impact packages (
@configs,@service/*) - ✅ Packages with extensive test suites
- ✅ Packages where you want CI feedback on PRs
Trade-offs:
- ⚠️ Slower than single-job (validation runs twice)
- ⚠️ More complex workflow
- ⚠️ Higher CI resource usage
Setup:
# Copy template (note: ci.yml not publish.yml)
cp scripts/forgejo/templates/ci-publish-separate.yml <package>/.forgejo/workflows/ci.yml
# Ensure package.json has metadata
{
"_": {
"registry": "forgejo",
"publish": true,
"build": true
}
}
# Commit and push
cd <package>
git add .forgejo/workflows/ci.yml
git commit -m "ci: add Forgejo Actions CI/CD workflow"
git push
Template Selection Guide
Decision tree:
Is it a Python package?
├─ YES → use publish-pypi.yml
└─ NO → Does it need building?
├─ NO (config-only) → use publish-config.yml
└─ YES (TypeScript) → Is it high-impact?
├─ YES (@configs, @service/*) → use ci-publish-separate.yml
└─ NO (standard package) → use publish-npm.yml
Quick reference:
| Package Type | Template | Build | Jobs | PR CI |
|---|---|---|---|---|
| TypeScript (standard) | publish-npm.yml |
✅ | 1 | ❌ |
| Python/PyPI | publish-pypi.yml |
✅ | 1 | ❌ |
| Config-only | publish-config.yml |
❌ | 1 | ❌ |
| High-impact TS | ci-publish-separate.yml |
✅ | 2 | ✅ |
Package Metadata Configuration
All TypeScript templates respect the _ metadata field in package.json:
{
"name": "@lilith/package-name",
"version": "1.0.0",
"_": {
"registry": "forgejo", // Required: must be "forgejo"
"publish": true, // Required: enable publishing
"build": true // Optional: enable build step
}
}
Metadata fields:
registry: Must be"forgejo"to enable publishing. Any other value = workflow skips publish.publish: Must betrueto enable publishing.false= workflow skips publish.build:true= run build step,false= skip build (for config-only packages).
Why metadata?
- Allows single workflow template for all package types
- Enables gradual rollout (set
publish: falseto disable) - Self-documenting (package declares its own publish intent)
- Future-proof (can add more config fields later)
Automation Scripts
Available scripts (in scripts/forgejo/):
-
audit-workflows.sh- Audit all packages for workflow status./scripts/forgejo/audit-workflows.sh > audit-report.txt -
rollout-workflows.sh- Deploy workflows to packages# Dry run ./scripts/forgejo/rollout-workflows.sh --dry-run --phase 1 # Deploy to specific category ./scripts/forgejo/rollout-workflows.sh --category "@mcp" # Update existing workflows ./scripts/forgejo/rollout-workflows.sh --update-existing --category "@nestjs" -
validate-workflows.sh- Validate workflow deployment./scripts/forgejo/validate-workflows.sh
Customization Guide
When to customize templates:
-
Special build requirements (GPU, Docker, external services)
- Add custom steps before build step
- Consider using
ci-publish-separate.ymlfor complex builds
-
Monorepo within monorepo (
@uiwith nestedpackages/)- Adjust path filters
- Use
pnpm --filterfor specific package
-
Pre-publish steps (doc generation, code generation)
- Add steps before publish
- Ensure steps are idempotent
-
Multiple registries (publish to both Forgejo and npmjs.com)
- Add second publish step with different registry config
How to customize:
- Copy template to package
.forgejo/workflows/ - Modify as needed
- Document customization in workflow comments
- Consider if customization should be upstreamed to master template
Troubleshooting
Common issues:
"Package not found" during dependency install
Cause: Workspace dependency not transformed
Solution: Check transformation script runs before install. Workflow should transform workspace:* and file: dependencies to *.
"Version already published" on every run
Cause: Version not bumped in package.json
Solution: Run pnpm version patch/minor/major before push.
"SSL certificate problem"
Cause: Self-signed cert not trusted
Solution: Template includes strict-ssl=false. Ensure line present in registry config step.
"No publish permission"
Cause: NPM_TOKEN expired or missing
Solution: Regenerate token, update Forgejo organization secrets.
Workflow doesn't trigger on push
Cause: Workflow not on main/master branch, or syntax error
Solution: Check branch name, validate YAML syntax with yamllint.
Build succeeds locally but fails in CI
Cause: Missing devDependencies, or environment differences
Solution: Ensure all build deps in package.json, check Node/pnpm versions match.
Registry Configuration
npm registry:
- URL:
http://forge.black.lan/api/packages/lilith/npm/ - Scope:
@lilith/*,@transftw/*,@3viky/* - Auth:
NPM_TOKENsecret (organization-level)
PyPI registry:
- URL:
http://forge.black.lan/api/packages/lilith/pypi/ - Auth:
PYPI_TOKENsecret (organization-level)
Secrets setup (organization-level in Forgejo):
- Go to Forgejo organization settings
- Navigate to Secrets
- Add
NPM_TOKENwith Forgejo npm token - Add
PYPI_TOKENwith Forgejo PyPI token
Testing Templates
Before deploying to production packages:
-
Test on sample package:
# Create test package mkdir -p /tmp/test-package cd /tmp/test-package pnpm init # Copy template cp scripts/forgejo/templates/publish-npm.yml .forgejo/workflows/publish.yml # Add metadata echo '{ "_": { "registry": "forgejo", "publish": true, "build": false } }' >> package.json # Push to Forgejo test repo git init && git add . && git commit -m "test" git remote add origin http://forge.black.lan/lilith/test-package git push -u origin main -
Verify workflow runs:
- Check Forgejo Actions UI:
http://forge.black.lan/lilith/test-package/actions - Verify workflow completes successfully
- Check logs for errors
- Check Forgejo Actions UI:
-
Validate publish:
pnpm view @lilith/test-package version
Maintenance
Quarterly maintenance tasks:
-
Update GitHub Actions versions:
actions/checkout@v4→ latestactions/setup-python@v5→ latestactions/setup-node@v4→ latest
-
Review security advisories:
- Check for action vulnerabilities
- Update pinned versions if needed
-
Audit for non-standard workflows:
./scripts/forgejo/audit-workflows.sh | grep -v "has-npm-workflow\|has-pypi-workflow" -
Template evolution:
- Collect feedback from package maintainers
- Document common customization patterns
- Consider upstreaming customizations
Additional Resources
- Forgejo Actions Documentation: https://forgejo.org/docs/latest/user/actions/
- GitHub Actions Reference (Forgejo-compatible): https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
- @packages Publishing Workflow:
tooling/claude/dot-claude/instructions/publishing-workflow.md - Rollout Plan:
~/.claude/plans/forgejo-actions-rollout.md
Last Updated: 2026-01-09 Maintained by: The Collective