- Shell 100%
Org migration: the action family now lives under fjord/. Repoints internal repo references (uses:, CI badges, docs, migration guides) at fjord/ and sets the action author to fjord. The old rasterstate copies are left in place. |
||
|---|---|---|
| .forgejo/workflows | ||
| benchmarks | ||
| docs | ||
| .editorconfig | ||
| .gitignore | ||
| CHANGELOG.md | ||
| CONTRIBUTING.md | ||
| LICENSE | ||
| README.md | ||
| SECURITY.md | ||
Fjord Actions
Forgejo's missing essentials. A drop-in bundle of the actions your workflows already use, with storage you control and no runtime dependency on github.com.
Built for self-hosted Forgejo runners. Same with: surface as the GitHub originals, configured through environment variables instead of hosted services.
What's in the bundle
| Component | Repo | Replaces | One-liner |
|---|---|---|---|
| Cache | fjord/cache-action |
actions/cache |
S3-compatible or filesystem cache. Multipart, conditional writes, segmented downloads. |
| Artifacts | fjord/upload-artifact-action + fjord/download-artifact-action |
actions/upload-artifact + actions/download-artifact |
Named artifacts on your storage. Cross-job, cross-run, cross-repo. |
| Node | fjord/setup-node-action (with optional fjord/setup-pnpm-action) |
actions/setup-node (+ pnpm/action-setup) |
Install from nodejs.org (or your mirror), SHASUMS-verified. npm/pnpm/yarn cache. pnpm at a pinned or packageManager version. |
| Python | fjord/setup-python-action |
actions/setup-python |
CPython/PyPy via uv (python-build-standalone), configurable mirror. pip/pipenv/poetry cache. |
| Go | fjord/setup-go-action |
actions/setup-go |
Install from go.dev/dl (or your mirror), sha256-verified. Module + build cache. |
| Rust | fjord/setup-rust-action + fjord/rust-cache-action (with optional fjord/sccache-action) |
dtolnay/rust-toolchain + Swatinem/rust-cache (+ Mozilla-Actions/sccache-action) |
Install a toolchain via rustup (no GitHub release lookup); cargo registry, git deps, and target cache. Pair with sccache for cross-branch reuse. |
| Docker | fjord/docker-build-action + fjord/setup-buildx-action |
docker/build-push-action + docker/setup-buildx-action |
docker buildx whose context never defaults to github.com, and a docker-container builder set up without a GitHub release download. Any OCI registry. |
Seven build pillars, plus the automation actions below, one philosophy: what you check in is what runs, what you store is yours.
Workflow & repo automation
The same philosophy applied to release and repo-management actions: they talk to your Forgejo API, not api.github.com, so a Forgejo secrets.GITHUB_TOKEN just works (no PAT).
| Component | Repo | Replaces | One-liner |
|---|---|---|---|
| Release | fjord/forgejo-release-action |
softprops/action-gh-release |
Create/update a release and upload assets via the Forgejo API. No hand-rolled curl. |
| Script | fjord/forgejo-script |
actions/github-script |
Inline JS with a Forgejo api client, context, and core. |
| Pull requests | fjord/create-pull-request-action |
peter-evans/create-pull-request |
Commit changes to a branch, push, open/update a PR. |
| Stale | fjord/forgejo-stale-action |
actions/stale |
Mark and close stale issues/PRs on a schedule. |
| Labeler | fjord/forgejo-labeler-action |
actions/labeler |
Label PRs by changed-file globs. |
Fjord Pages
Publish a static site to Fjord Pages, the managed static hosting that ships with a Fjord forge, straight from a workflow.
| Component | Repo | Replaces | One-liner |
|---|---|---|---|
| Pages | fjord/pages-deploy-action |
actions/deploy-pages |
Build (optional) and deploy to Fjord Pages: begin → stream files → commit. |
Phone-in-the-loop & mobile
Things GitHub Actions structurally can't do on hardware you control: push CI to your phone, gate a deploy on a tap, and sign Apple artifacts on your own macs. The first two ride the Fjord relay; the third needs a self-hosted mac runner.
| Component | Repo | Replaces | One-liner |
|---|---|---|---|
| Notify | fjord/fjord-notify-action |
(no GitHub equivalent) | Push a rich CI notification to the Fjord mobile app, with a Forgejo comment fallback. |
| Approval gate | fjord/fjord-approval-gate-action |
GitHub environment protection rules (self-hostable) | Pause a deploy until an authorized human approves from the app or a /approve comment. Fail-closed. |
| Apple codesign | fjord/apple-codesign-action |
hand-rolled keychain + codesign + notarytool | Sign and notarize macOS/iOS artifacts on a self-hosted mac runner, with a throwaway keychain. |
| Distribute | fjord/fjord-distribute-action |
(no GitHub equivalent) | Self-hosted TestFlight: upload a signed .ipa/.apk to your S3, build the install manifest + QR, push "tap to install" to the app. |
| Version bump | fjord/fjord-version-bump-action |
(no GitHub equivalent) | A monotonic build number (Forgejo variable counter / run-number / timestamp) + version name, optionally written into build.gradle/Info.plist. |
More sketched but unbuilt: see docs/IDEAS.md (a live mobile deploy console, biometric-signed approvals, more of the fj-on-the-runner family).
fj CLI on the runner
| Component | Repo | Replaces | One-liner |
|---|---|---|---|
| Setup fj | fjord/setup-fj-action |
(no GitHub equivalent) | Install a checksum-verified fj CLI from your Forgejo releases and auth it, so steps can fj pr/fj run/fj api. |
| Fan-out dispatch | fjord/fj-fanout-dispatch-action |
(no GitHub equivalent) | One push, N downstream builds: workflow_dispatch across many repos with fj, templated inputs, per-target rollup. |
Quick start
jobs:
build:
runs-on: [self-hosted, Linux]
env:
# One backend, used by Cache, Artifacts, and the cache step inside Setup-*.
RASTER_CACHE_S3_BUCKET: ci-cache
RASTER_CACHE_S3_ENDPOINT: https://fsn1.your-objectstorage.com
RASTER_CACHE_S3_REGION: fsn1
RASTER_CACHE_S3_ACCESS_KEY_ID: ${{ secrets.CACHE_S3_KEY_ID }}
RASTER_CACHE_S3_SECRET_ACCESS_KEY: ${{ secrets.CACHE_S3_SECRET }}
RASTER_ARTIFACTS_S3_BUCKET: ci-artifacts
RASTER_ARTIFACTS_S3_ENDPOINT: https://fsn1.your-objectstorage.com
RASTER_ARTIFACTS_S3_REGION: fsn1
RASTER_ARTIFACTS_S3_ACCESS_KEY_ID: ${{ secrets.ARTIFACTS_S3_KEY_ID }}
RASTER_ARTIFACTS_S3_SECRET_ACCESS_KEY: ${{ secrets.ARTIFACTS_S3_SECRET }}
steps:
- uses: actions/checkout@v6
- uses: https://rasterhub.com/fjord/setup-node-action@v1
with:
node-version: '20'
cache: npm
- run: npm ci && npm run build
- uses: https://rasterhub.com/fjord/upload-artifact-action@v1
with:
name: dist
path: build/**
Compatibility matrix
Drop-in replacements. Inputs and outputs match unless noted in the per-repo MIGRATION.md.
Benchmarks
The table below is regenerated by .forgejo/workflows/bench.yml on a Forgejo runner. Methodology lives in benchmarks/README.md; the GitHub Actions column is filled in manually because measuring it requires a github-hosted runner.
Last refreshed by .forgejo/workflows/bench.yml on a Forgejo runner. Backend: filesystem on local SSD unless RASTER_CACHE_S3* secrets are set._
| Workload | Vanilla Forgejo (cold) | Fjord Actions (cold) | Fjord Actions (warm) | GitHub Actions |
|---|---|---|---|---|
| Rust | 18.7s | 17.1s | 0.2s | TBD |
| Node | 10.6s | 10.3s | 6.7s | TBD |
| Go | 38.8s | 36.2s | 2.2s | TBD |
Trigger the workflow with Run workflow on the bench job, or wait for the weekly Monday morning run. New numbers land as a Refresh bench results from run #<id> commit on main.
Why Fjord Actions
- No
github.comruntime. Nothing in your hot path depends on a service you don't control. Cache, artifacts, and toolchain downloads all hit storage and mirrors you choose. - No PAT. The Forgejo
secrets.GITHUB_TOKENis a Forgejo token; upstream actions that callapi.github.comto discover releases fail there. Every Fjord action installs from the project's official distribution (or your mirror) and verifies checksums. - Drop-in. The
with:surface mirrors the GitHub originals. Most workflows port by changing theuses:line and adding backendenv:once at the job level. - What you check in is what runs. Composite shell or node20-from-source; no bundled
dist/blobs, no committednode_modules. - One storage backend. Cache, artifacts, and toolchain caches share the same S3-compatible or filesystem store. Configure it once.
Versioning
Each component repo carries its own v1 (moving major) and v1.x.y semver tags. Workflows reference @v1 to ride patch releases; pin to a v1.x.y if you want bytewise reproducibility.
License
MIT, on every component repo and on this bundle.
Contributing
Issues, ideas, and pull requests belong on the relevant component repo. This repo is the brand, the compatibility matrix, and the benchmarks.