# Forgejo Actions | Advanced features

This page covers the more advanced features of Forgejo Actions.

## pre-commit hook

A [`pre-commit` hook](https://pre-commit.com/) is provided to assist in
validating Forgejo Actions files in your projects.
See [pre-commit.com](https://pre-commit.com/) for detailed instructions on how
to set it up, as well as more details on how it works, and then add this to
your `.pre-commit-config.yaml` file:

```yaml
repos:
  - repo: https://code.forgejo.org/forgejo/runner
    rev: v11.1.1
    hooks:
      - id: forgejo-runner-validate
```

## Artifacts

`Artifacts` let you persist data after a job has completed. An artifact is a file or collection of files produced during a workflow run.

This has two main uses:

- Storing non-permanent data after a workflow finishes, like test results.
- Storing data generated in one job, so another job later in the same workflow can use it.

Artifacts expire after a delay of 90 days by default, but this may be changed by the instance admin.

The artifacts created by a workflow can be downloaded from the web
interface that shows the the details of the jobs for a workflow.

![download artifacts](https://docs.cocobook.com/uploads/images/gallery/2026-10/actions-download-artifact.png)

[Check out the example](https://code.forgejo.org/forgejo/end-to-end/src/branch/main/actions/example-artifacts/.forgejo/workflows)
based on the [upload-artifact](https://code.forgejo.org/actions/upload-artifact) action and
the [download-artifact](https://code.forgejo.org/actions/download-artifact) action.

> **NOTE:** The name of an artifact is limited to 255 characters.

> **NOTE:** It is not currently possible to access artifacts from other workflow runs within forgejo [#8004](https://codeberg.org/forgejo/forgejo/issues/8004).

> **NOTE:** When using upload and download actions you must use v3 or patched v4 as demonstrated [here](https://code.forgejo.org/forgejo/end-to-end/src/branch/main/actions/example-artifacts-v4/.forgejo/workflows/test.yml).

## Uploading to a package registry

Forgejo offers built-in [package registries](/link/1160). You can use these to publish packages for various package managers, or just [generic](/link/1172) build output.

## Cache

You can use the `Cache` to reuse commonly used files from previous workflow runs, like package downloads or intermediary build results.

Some Actions will automatically use the cache. For
instance the [setup-go](https://code.forgejo.org/actions/setup-go) action will do that by default to save downloading and compiling packages found in `go.mod`.

It is also possible to explicitly control what is cached (and when)
by using the [actions/cache](https://code.forgejo.org/actions/cache) action.
Caching makes no guarantees that a cache will be populated, even when two
`jobs` are run in sequence. If you want to reliably exchange information
between `jobs`, see [`artifacts`](#bkmrk-artifacts).

See also the [set of examples](https://code.forgejo.org/forgejo/end-to-end/src/branch/main/actions/example-cache/.forgejo/workflows/).

> **NOTE:** [actions/cache](https://code.forgejo.org/actions/cache) will use `zstd` if present when compressing files to be sent to the cache. It is faster than the default compression. A container which does not have `zstd` installed _will not_ be able to decompress the cache and will continue without. In general it is recommended to ensure that if you're using `zstd` in one place in your project, you use it everywhere.

> **NOTE:** if the runner is not configured to provide a cache, [actions/cache](https://code.forgejo.org/actions/cache) will fail with the following error: `Cache action is only supported on GHES version >= 3.5`.

### Caching with Podman

Since version 5, when used with [Pasta](https://passt.top/), which is the default, Podman copies the IP of the primary interface of the host into containers. Therefore, it is not possible to connect to the host using the host's primary IP address, which is the method used by `actions/cache`. It manifests in errors like `::warning::Failed to restore: getCacheEntry failed: connect ECONNREFUSED 192.168.124.60:41275`.

There are multiple options to deal with it.

One option is to configure Podman not to use the host's primary IP address for containers; see the article [Podman 5.0 breaking changes in detail](https://blog.podman.io/2024/03/podman-5-0-breaking-changes-in-detail/), section "Pasta default for rootless networking".

Another option is to change the Forgejo Runner configuration to use the "magic" host name `host.containers.internal`:

```yaml
cache:
  proxy_port: 4000
  actions_cache_url_override: 'http://host.containers.internal:4000'
```

However, that is only an option if a particular Forgejo Runner instance only uses Podman as a back-end and not, for example, Podman and LXC, because all back-ends would receive `http://host.containers.internal:4000` as cache URL.

## Services

Services like databases can be started from container images and are then available to all steps in a particular job:

```yaml
job:
  my-job:
    runs-on: docker
    services:
      pgsql:
        image: postgres:15
        env:
          POSTGRES_DB: test
          POSTGRES_PASSWORD: postgres
    ...
```

A container with the specified `image:` is run before the job starts and is terminated when it completes. The job can address the service using its name, in this case `pgsql`.

The IP address of `pgsql` is on the same [network](https://docs.docker.com/engine/reference/commandline/network/) as the container running the **steps** and there is no need for port binding. The `postgres:15` image exposes the PostgreSQL port 5432 and a client will be able to connect as [shown in this example](https://code.forgejo.org/forgejo/end-to-end/src/branch/main/actions/example-service/.forgejo/workflows/test.yml).

> **NOTE:** services are only supported with the `docker` backend, not with the `lxc` backend.

> **NOTE:** services require [`[container].network`](https://forgejo.org/docs/v15.0/admin/actions/runner-installation/#configuration) to be empty so that a new network can be temporarily created to connect the container running the workflow with the services.

See the [reference](/link/1143) for the list of supported options. There are also a number of [examples that illustrate the configuration and usage of services](https://code.forgejo.org/forgejo/end-to-end/src/branch/main/actions/example-service/.forgejo/workflows/).
