+++ title = "Swapping from GitHub to Forgejo actions, with `Nix` based actions" date = 2025-08-27 [taxonomies] tags = ["forgejo", "nix", "CI", "actions", "docker"] +++ ## Forgejo Actions Most actions are the mostly the same, but some things, like conncrurrency groups don't work. ```yaml name: nix on: pull_request: branches: [main] push: schedule: - cron: 0 0 * * 1 env: CARGO_TERM_COLOR: always NIX_CONFIG: "experimental-features = nix-command flakes" jobs: check-dependencies: name: check-dependencies # Change to a valid Forgejo runner image # runs-on: ubuntu-latest runs-on: nix permissions: contents: read id-token: write actions: write steps: - run: nix run -I nixpkgs=channel:nixos-unstable nixpkgs#attic-client login https://nix.example.com ${{ secrets.ATTIC_TOKEN }} || true - run: nix run -I nixpkgs=channel:nixos-unstable nixpkgs#attic-client cache create || true - run: nix run -I nixpkgs=channel:nixos-unstable nixpkgs#attic-client cache configure -- --priority 30 || true - run: nix run -I nixpkgs=channel:nixos-unstable nixpkgs#attic-client use || true # Install and configure Node.js, since it's not setup in the default nix - name: Install Node.js run: | mkdir -p ~/.local/bin nix build -I nixpkgs=channel:nixos-unstable nixpkgs#nodejs_24 -o ~/.local/nodejs ln -sf ~/.local/nodejs/bin/node ~/.local/bin/node ln -sf ~/.local/nodejs/bin/npm ~/.local/bin/npm echo "$HOME/.local/bin" >> $GITHUB_PATH - uses: actions/checkout@v5 - run: nix build -I nixpkgs=channel:nixos-unstable nixpkgs#nix-fast-build - name: check run: | nix run -I nixpkgs=channel:nixos-unstable nixpkgs#nix-fast-build -- --no-nom --skip-cached - name: Push to attic if: always() run: | valid_paths="" for path in /nix/store/*/; do if nix path-info "$path" >/dev/null 2>&1; then valid_paths="$valid_paths $path" fi done if [ -n "$valid_paths" ]; then for i in {1..10}; do nix run -I nixpkgs=channel:nixos-unstable nixpkgs#attic-client push nextrack $valid_paths && break || [ $i -eq 5 ] || sleep 5 done fi ``` ## Forgejo Actions ```json # .runner { "WARNING": "This file is automatically generated by act-runner. Do not edit it manually unless you know what you are doing. Removing this file will cause act runner to re-register as a new runner.", "id": 1, "uuid": "****", "name": "", "token": "****", "address": "https://git.example.com", "labels": [ "bookworm:docker://node:24-bookworm", "nix-base:docker://docker.nix-community.org/nixpkgs/nix-unstable:latest", "nix:docker://git.nexveridian.com/nexveridian/action-attic:latest" ] } ``` ### Available runner images - bookworm: closest to GitHub actions - nix-base: for bootstrapping - nix: custom image with packages pre installed ## Creating custom runner images `git clone ssh://git@git.nexveridian.com:222/NexVeridian/docker-nixpkgs.git` ### Create a copy of `images/action-attic` ```nix { docker-nixpkgs, pkgs, attic-client, nodejs_24, nix-fast-build, # add more packages here }: (docker-nixpkgs.nix.override { nix = pkgs.nixVersions.latest; extraContents = [ attic-client nodejs_24 nix-fast-build # and the corresponding packages here ]; }).overrideAttrs (prev: { meta = (prev.meta or { }) // { description = "Forgejo action image, with Nix and Attic client"; }; }) ``` ### Edit folder name in `.forgejo/workflows/nix.yaml` ```yaml - name: Build Nix package run: nix-build -A action-attic ``` ## Pushing docker container images With GitHub actions most people use `docker push` to push their images to a registry. With Forgejo actions, that probably won't work. because of docker-in-docker. Instead, you can use the `skopeo` to push your images to a registry. To Setup `CONTAINER_TOKEN`: - create a token https://git.example.com/user/settings/applications - then add the token to your secrets https://forgejo.example.com/user/settings/actions/secrets ```yaml name: docker on: push: branches: [main] env: REGISTRY: git.nexveridian.com IMAGE_NAME: ${{ github.repository }} NIX_CONFIG: "experimental-features = nix-command flakes" CONTAINER_TOKEN: ${{ secrets.CONTAINER_REGISTRY_TOKEN }} jobs: build: runs-on: nix permissions: contents: read packages: write id-token: write steps: - run: nix run -I nixpkgs=channel:nixos-unstable nixpkgs#attic-client login nex https://nix.example.com ${{ secrets.ATTIC_TOKEN }} || true - run: nix run -I nixpkgs=channel:nixos-unstable nixpkgs#attic-client cache create || true - run: nix run -I nixpkgs=channel:nixos-unstable nixpkgs#attic-client cache configure -- --priority 30 || true - run: nix run -I nixpkgs=channel:nixos-unstable nixpkgs#attic-client use || true - name: Install Node.js run: | mkdir -p ~/.local/bin nix build -I nixpkgs=channel:nixos-unstable nixpkgs#nodejs_24 -o ~/.local/nodejs ln -sf ~/.local/nodejs/bin/node ~/.local/bin/node ln -sf ~/.local/nodejs/bin/npm ~/.local/bin/npm echo "$HOME/.local/bin" >> $GITHUB_PATH - uses: actions/checkout@v4 - name: Install skopeo run: | mkdir -p ~/.local/bin nix build -I nixpkgs=channel:nixos-unstable nixpkgs#skopeo -o ~/.local/skopeo ln -sf ~/.local/skopeo/bin/skopeo ~/.local/bin/skopeo echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Build Nix package run: nix build .#my-docker - name: Prepare repository variables run: | echo "REPO=${GITHUB_REPOSITORY,,}" >> ${GITHUB_ENV} echo "OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> ${GITHUB_ENV} # Extract just the repository name (everything after the last slash) REPO_NAME=${GITHUB_REPOSITORY##*/} echo "IMAGE_NAME=${REPO_NAME,,}" >> ${GITHUB_ENV} - name: Setup skopeo policy and push image run: | # configure container policy to accept insecure registry mkdir -p ~/.config/containers cat > ~/.config/containers/policy.json < ~/.docker/config.json </dev/null 2>&1; then valid_paths="$valid_paths $path" fi done if [ -n "$valid_paths" ]; then for i in {1..10}; do nix run -I nixpkgs=channel:nixos-unstable nixpkgs#attic-client push $valid_paths && break || [ $i -eq 5 ] || sleep 5 done fi ```