Forgejo gets an integrated CI named Actions

Prior to Forgejo v1.19 running CI jobs required a third party software such as Woodpecker CI. It has its own web interface, relies on webhooks to be notified something changed in a repository and relies on the Forgejo API to figure out user permissions or access to private repositories. When it is finished, the error or success is also sent back to Forgejo via the API, with a link the user needs to click to get more details. It works well enough and Forgejo has been using Woodpecker CI from day one, for testing pull requests or publishing releases.

With v1.19 comes an experimental CI (not ready for production just yet) integrated in Forgejo. The CI jobs are configured with a syntax that is similar to GitHub Actions:

# .forgejo/workflows/demo.yaml
name: Demo
run-name: ${{ }} is testing
on: [push]
    runs-on: ubuntu-latest
      - run: echo "The job was automatically triggered by a ${{ github.event_name }} event."
      - run: echo "This job is now running on a ${{ runner.os }} server."
      - run: echo "The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
      - name: Check out repository code
        uses: actions/checkout@v3
      - run: echo "The ${{ github.repository }} repository has been cloned to the runner."
      - run: echo "The workflow is now ready to test your code on the runner."
      - name: List files in the repository
        run: |
          ls ${{ github.workspace }}
      - run: echo "This job's status is ${{ job.status }}."

And the results are displayed in the Forgejo web interface:

Running actions

Try it out

WARNING: The following procedure was effective for setting up a test instance when early versions of the Forgejo runner were under development, but the details are now outdated. Precompiled runner binaries are available and you should refer to the Forgejo Actions administrator documentation for runner setup instructions.

  • Create a Forgejo v1.19 instance with the user root password admin1234
    docker run --name forgejo -e FORGEJO__security__INSTALL_LOCK=true -e FORGEJO__actions__ENABLED=true -d
    docker exec --user 1000 forgejo forgejo admin user create --admin --username root --password admin1234 --email
  • Get the IP of the Forgejo instance ( in the following)
    docker exec --user 1000 forgejo ip a
  • Login at with user root password admin1234
  • Create a test project and activate actions in the settings Actions settings
  • Get the runner token from the runner tab in the Site administration (mytoken in the following) Register runner
  • Register and start the runner
    git clone
    cd runner
    git checkout v1.1.0
    make build
    ./forgejo-runner register --name myrunner --no-interactive --instance --token mytoken
    ./forgejo-runner daemon
  • Add the .forgejo/workflows/demo.yaml file above to the test repository, via the web interface
  • Go to the Actions tab of the project and watch it run to completion Running actions

How does it work?

The forgejo-runner creates a docker container and runs the job inside it. It can be shell commands (e.g. ls ${{ github.workspace }}) or actions (e.g. uses: actions/checkout@v3). The actions are references to repositories that are cloned and executed. For instance actions/checkout will clone

The container image used to run the container is specified by runs-on: ubuntu-latest but it may not contain all the tools required to complete the job. Reason why some actions are allowed to create a new container based on other images. In the end a single job may involve running multiple containers and they are all terminated when the job completes.


The implementation is very new and has many limitations which makes it unfit for production.

  • There is no support to run services such as a Postgres database
  • The container running the job is not systemd capable
  • There is no guarantee of compatibility with GitHub Actions, although the syntax of the files and the terminology is similar

Under the hood

The Forgejo runner is a new addition to the Forgejo dependencies (git & ssh) and is not yet packaged, it must be built from sources as explained above. It is a thin layer on top of ACT which implements the core of the logic to interpret and run the jobs. A soft fork of ACT is used and contains commits that are not yet submitted or accepted upstream.