Forgejo's missing essentials: cache, artifacts, toolchains, and builds without github.com
Find a file
Stephen Way 3bc34b1a79
Repoint references from rasterstate to fjord org
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.
2026-06-03 16:17:15 -07:00
.forgejo/workflows Repoint references from rasterstate to fjord org 2026-06-03 16:17:15 -07:00
benchmarks Repoint references from rasterstate to fjord org 2026-06-03 16:17:15 -07:00
docs Repoint references from rasterstate to fjord org 2026-06-03 16:17:15 -07:00
.editorconfig Brand the Fjord Actions bundle: README, compat matrix, benchmarks 2026-05-29 21:05:40 -07:00
.gitignore Brand the Fjord Actions bundle: README, compat matrix, benchmarks 2026-05-29 21:05:40 -07:00
CHANGELOG.md Repoint references from rasterstate to fjord org 2026-06-03 16:17:15 -07:00
CONTRIBUTING.md Brand the Fjord Actions bundle: README, compat matrix, benchmarks 2026-05-29 21:05:40 -07:00
LICENSE Brand the Fjord Actions bundle: README, compat matrix, benchmarks 2026-05-29 21:05:40 -07:00
README.md Repoint references from rasterstate to fjord org 2026-06-03 16:17:15 -07:00
SECURITY.md Brand the Fjord Actions bundle: README, compat matrix, benchmarks 2026-05-29 21:05:40 -07:00

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.

GitHub Action Fjord Replacement Migration notes
actions/cache fjord/cache-action migration
actions/upload-artifact fjord/upload-artifact-action migration
actions/download-artifact fjord/download-artifact-action migration
actions/setup-node fjord/setup-node-action migration
pnpm/action-setup fjord/setup-pnpm-action migration
actions/setup-python fjord/setup-python-action migration
actions/setup-go fjord/setup-go-action migration
dtolnay/rust-toolchain fjord/setup-rust-action migration
Swatinem/rust-cache fjord/rust-cache-action migration
docker/build-push-action fjord/docker-build-action migration
docker/setup-buildx-action fjord/setup-buildx-action migration
Mozilla-Actions/sccache-action (optional) fjord/sccache-action Compiler cache for the Rust pillar.
softprops/action-gh-release fjord/forgejo-release-action migration
actions/github-script fjord/forgejo-script migration
peter-evans/create-pull-request fjord/create-pull-request-action migration
actions/stale fjord/forgejo-stale-action migration
actions/labeler fjord/forgejo-labeler-action migration

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.com runtime. 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_TOKEN is a Forgejo token; upstream actions that call api.github.com to 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 the uses: line and adding backend env: once at the job level.
  • What you check in is what runs. Composite shell or node20-from-source; no bundled dist/ blobs, no committed node_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.