Commit graph

787 commits

Author SHA1 Message Date
Roman K.
f48e9b3ba6 fix: prevent premature token revocation in reusable workflows (#1081)
## Problem

When using reusable workflows, the Forgejo runner prematurely revokes `GITHUB_TOKEN` after the first step completes, causing subsequent steps to fail with authentication errors.

### Reproduction

When the reusable workflow contains multiple steps that require authentication:
1. First step (e.g., checkout) completes successfully
2. Reporter receives completion banner from child workflow
3. Token is revoked prematurely
4. Second step fails with authentication error

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- bug fixes
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1081): <!--number 1081 --><!--line 0 --><!--description Zml4OiBwcmV2ZW50IHByZW1hdHVyZSB0b2tlbiByZXZvY2F0aW9uIGluIHJldXNhYmxlIHdvcmtmbG93cw==-->fix: prevent premature token revocation in reusable workflows<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1081
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.code.forgejo.org>
Co-authored-by: Roman K. <devops@syncstack.net>
Co-committed-by: Roman K. <devops@syncstack.net>
2025-10-14 01:45:54 +00:00
Andrew Cassidy
2d359067f6
fix: don't prepend server URL with https:// if it's an empty string (#1083)
An attempt to address #1074 in a way that makes everyone happy

Right now, any server URL that doesnt start with `http://` or `https://` automatically gets `https://` prepended to it. When no instance is set while running `forgejo-runner exec` this results in the `{FORGEJO,GITHUB}_SERVER_URL` environment variables being set to simply "https://". Any action using the GitHub actions toolkit chokes on this as an invalid URL and fails the run with a nondescript error. This PR instead leaves empty strings alone, which the actions toolkit seems much happier with

Alternate fixes:
* default the `--forgejo-instance` flag to a valid but unresolved url like 'http://example.com' so the actions don't crash
* don't set the environment variables at all when the server URL is an empty string. This causes the actions toolkit to assume GitHub.com as a fallback

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- bug fixes
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1083): <!--number 1083 --><!--line 0 --><!--description Zml4OiBkb24ndCBwcmVwZW5kIHNlcnZlciBVUkwgd2l0aCBodHRwczovLyBpZiBpdCdzIGFuIGVtcHR5IHN0cmluZw==-->fix: don't prepend server URL with https:// if it's an empty string<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1083
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: Andrew Cassidy <drewcassidy@me.com>
Co-committed-by: Andrew Cassidy <drewcassidy@me.com>
2025-10-12 08:53:45 +00:00
Andrew Cassidy
c80a40023c
feat: disambiguate cloud emoji (#1076)
Many emoji technically have two forms, the colorful form and the monochrome text form. For some reason, on macOS, ☁️ defaults to the latter, which is also really tiny for some reason?. Adding the invisible emoji variant selector (U+FE0F) causes it to always render as the colorful full-width graphic

Before:

![Screenshot 2025-10-08 at 22.53.36](/attachments/beaeea4a-d355-4db6-9cca-2425a62b6ea9)

After:

![Screenshot 2025-10-08 at 22.53.14](/attachments/dd670d38-fed6-41dc-a0c2-421846bc26bd)

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- other
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1076): <!--number 1076 --><!--line 0 --><!--description ZGlzYW1iaWd1YXRlIGNsb3VkIGVtb2pp-->disambiguate cloud emoji<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1076
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Andrew Cassidy <drewcassidy@me.com>
Co-committed-by: Andrew Cassidy <drewcassidy@me.com>
2025-10-11 09:23:28 +00:00
Mathieu Fenniak
02247b852a fix: allow mapping into env variable INPUT_N from ${{ inputs.n }} (#1080)
When using a reusable workflow such as:
```yaml
name: "use-inputs-impl"

on:
  workflow_call:
    inputs:
      image:
        description: "Image to be used in job"
        type: string
        required: false
        default: "docker.io/alpine:3.22"
      condition:
        description: "Only run a job if this is true"
        type: string
        required: false
        default: false

jobs:
  works:
    runs-on: docker
    container:
      image: alpine:3.22
    env:
      INPUT_IMAGE: ${{ inputs.image }}
      INPUT_CONDITION: ${{ inputs.condition }}
    steps:
      - run: echo "Hello world from Alpine"
      - run: cat /etc/alpine-release
      - run: echo "INPUT_IMAGE=$INPUT_IMAGE"
      - run: echo "INPUT_CONDITION=$INPUT_CONDITION"
```

The runner will currently output un-evaluated expressions:
```
INPUT_IMAGE=${{ inputs.image }}
INPUT_CONDITION=${{ inputs.condition }}
```

Internally, the workflow is using `INPUT_...` environment variables to transfer data into local reusable workflows, and the order of evaluation in `getEvaluatorInputs` was preferring to use the un-evaluated value, over the evaluated value.

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- bug fixes
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1080): <!--number 1080 --><!--line 0 --><!--description Zml4OiBhbGxvdyBtYXBwaW5nIGludG8gZW52IHZhcmlhYmxlIElOUFVUX04gZnJvbSAke3sgaW5wdXRzLm4gfX0=-->fix: allow mapping into env variable INPUT_N from ${{ inputs.n }}<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1080
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-10-10 21:55:08 +00:00
Earl Warren
66a7e82c43
feat: allow --memory in workflow container options (#1079)
First hand experience to implement this feature can be found at https://codeberg.org/forgejo/forgejo/issues/9406. In a nutshell it is a service container in the CI that randomly uses massive amounts of memory (>50GB RSS) but normally less than 100MB.

---

See also the [matching documentation pull request](https://codeberg.org/forgejo/docs/pulls/1539).

---

It is already possible to limit the memory used by all containers in the config file:

```yaml
container:
  options: --memory 200M
```

This limit can be further reduced (but not increased) by the same option in a job:

```yaml
jobs:
  job:
    runs-on: docker
    container:
      image: code.forgejo.org/oci/node:20-bookworm
      options: --memory 200M
    steps:
      - run: echo OK
```

or a service container:

```yaml
job:
  my-job:
    runs-on: docker
    services:
      pgsql:
        image: postgres:15
        options: --memory 1G
```

Refs https://docs.docker.com/engine/containers/resource_constraints/#limit-a-containers-access-to-memory

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- features
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1079): <!--number 1079 --><!--line 0 --><!--description ZmVhdDogYWxsb3cgLS1tZW1vcnkgaW4gd29ya2Zsb3cgY29udGFpbmVyIG9wdGlvbnM=-->feat: allow --memory in workflow container options<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1079
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.code.forgejo.org>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2025-10-10 14:33:07 +00:00
Mathieu Fenniak
3f52c56d1e feat: improve readability of error messages from ParseRawOn (#1063)
With https://codeberg.org/forgejo/forgejo/pulls/9530, the error messages from `ParseRawOn` are user-facing and need a pass to improve their meaning.

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- features
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1063): <!--number 1063 --><!--line 0 --><!--description ZmVhdDogaW1wcm92ZSByZWFkYWJpbGl0eSBvZiBlcnJvciBtZXNzYWdlcyBmcm9tIFBhcnNlUmF3T24=-->feat: improve readability of error messages from ParseRawOn<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1063
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-10-07 14:41:55 +00:00
Mathieu Fenniak
a3d46d7597
chore: add additional logging to cacheproxy (#1065)
In support of diagnosing #1064, I hope.

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- other
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1065): <!--number 1065 --><!--line 0 --><!--description Y2hvcmU6IGFkZCBhZGRpdGlvbmFsIGxvZ2dpbmcgdG8gY2FjaGVwcm94eQ==-->chore: add additional logging to cacheproxy<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1065
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-10-07 08:12:16 +00:00
limiting-factor
996ac343ee
chore(cleanup): lxc-helpers does not need a global lock (#1047)
- https://code.forgejo.org/forgejo/lxc-helpers/src/tag/v1.1.1 has  locking and atomicity
- this lock was only good for when two release templates are  populated simultaneously and not when it was interrupted

Refs forgejo/lxc-helpers#8

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- other
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1047): <!--number 1047 --><!--line 0 --><!--description V0lQOiBjaG9yZShjbGVhbnVwKTogbHhjLWhlbHBlcnMgZG9lcyBub3QgbmVlZCBhIGdsb2JhbCBsb2Nr-->WIP: chore(cleanup): lxc-helpers does not need a global lock<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1047
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: limiting-factor <limiting-factor@posteo.com>
Co-committed-by: limiting-factor <limiting-factor@posteo.com>
2025-10-03 16:15:43 +00:00
Earl Warren
413a52605d
fix: remove LXC backend leftovers when the job completes (#1054)
- remove the root of the LXC container after destroying it, with sudo as it may contain files owned by root while the runner id is not root
- os.RemoveAll only for native host runs, it is no longer needed for the LXC backend
- remove the CleanUp function that is an indirection with no use

Resolves forgejo/runner#442

When running the test from a non-root user and without this fix, it fails as follow:

```
go test -v -count=1 -run='TestRunnerLXC' ./internal/app/run
=== RUN   TestRunnerLXC
...
time="2025-10-03T15:05:12+02:00" level=debug msg=stopHostEnvironment
time="2025-10-03T15:05:13+02:00" level=debug msg="HostEnvironment.Remove /tmp/TestRunnerLXC1841090130/001/d29c1256e2912892/hostexecutor"
time="2025-10-03T15:05:13+02:00" level=error msg="Error while stop job container FORGEJO-ACTIONS-TASK-0_WORKFLOW-3ede81fbc69d42e6db70bef5820490fc3e7dc4d9dcbfb64981f2d00f08a30d6e_JOB-job: unlinkat /tmp/TestRunnerLXC1841090130/001/d29c1256e2912892/hostexecutor/some/directory/owned/by/root: permission denied"
=== NAME  TestRunnerLXC
    runner_test.go:469:
        	Error Trace:	/home/earl-warren/software/runner/internal/app/run/runner_test.go:469
        	            				/home/earl-warren/software/runner/internal/app/run/runner_test.go:496
        	Error:      	Received unexpected error:
        	            	Error occurred running finally: unlinkat /tmp/TestRunnerLXC1841090130/001/d29c1256e2912892/hostexecutor/some/directory/owned/by/root: permission denied (original error: <nil>)
        	Test:       	TestRunnerLXC
        	Messages:   	OK
=== NAME  TestRunnerLXC/OK
    testing.go:1679: test executed panic(nil) or runtime.Goexit: subtest may have called FailNow on a parent test
=== NAME  TestRunnerLXC
    testing.go:1267: TempDir RemoveAll cleanup: unlinkat /tmp/TestRunnerLXC1841090130/001/d29c1256e2912892/hostexecutor/some/directory/owned/by/root: permission denied
--- FAIL: TestRunnerLXC (6.84s)
    --- FAIL: TestRunnerLXC/OK (6.84s)
FAIL
FAIL	code.forgejo.org/forgejo/runner/v11/internal/app/run	6.847s
FAIL
```

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- bug fixes
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1054): <!--number 1054 --><!--line 0 --><!--description Zml4OiByZW1vdmUgTFhDIGJhY2tlbmQgbGVmdG92ZXJzIHdoZW4gdGhlIGpvYiBjb21wbGV0ZXM=-->fix: remove LXC backend leftovers when the job completes<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1054
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.code.forgejo.org>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2025-10-03 16:14:08 +00:00
cascading-pr
a980acd936
fix: make the creation of LXC templates atomic so they cannot be interrupted while building (#1049)
cascading-pr from https://code.forgejo.org/forgejo/lxc-helpers/pulls/49

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- other
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1049): <!--number 1049 --><!--line 0 --><!--description Y2FzY2FkaW5nLXByIGZyb20gaHR0cHM6Ly9jb2RlLmZvcmdlam8ub3JnL2Zvcmdlam8vbHhjLWhlbHBlcnMgcmVmcy9wdWxsLzQ5L2hlYWQgdG8gZm9yZ2Vqby9seGMtaGVscGVycy00OQ==-->cascading-pr from https://code.forgejo.org/forgejo/lxc-helpers refs/pull/49/head to forgejo/lxc-helpers-49<!--description-->
<!--end release-notes-assistant-->

Co-authored-by: cascading-pr <cascading-pr@example.com>
Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1049
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: cascading-pr <cascading-pr@noreply.code.forgejo.org>
Co-committed-by: cascading-pr <cascading-pr@noreply.code.forgejo.org>
2025-10-03 09:09:29 +00:00
Mathieu Fenniak
63351343ba
fix: improve logging to diagnose mystery job terminations (#1048)
Additional logging to support #1044.

Manual testing only.  Cases tested:

Cancel a job from Forgejo UI; this seems like the most likely missing piece in #1044 as two jobs were simultaneously marked as "Failed".  There are codepaths in Forgejo that can set this state to both cancelled and failed, but the runner didn't provide log output indicating that's why a job was stopping:
```
time="2025-10-02T13:22:53-06:00" level=info msg="UpdateTask returned task result RESULT_CANCELLED for a task that was in local state RESULT_UNSPECIFIED - beginning local task termination" func="[ReportState]" file="[reporter.go:410]"
```

Host-based executor hits step timeout in exec, or, is cancelled.  This occurred but only logged the `err` from `exec`, not the context error indicating whether it was a timeout or a cancellation:
```
[Test Action/job1] this step has been cancelled: ctx: context deadline exceeded, exec: RUN signal: killed
[Test Action/job1] this step has been cancelled: ctx: context canceled, exec: RUN signal: killed
```

Unable to `ReportState` due to Forgejo inaccessible.  If the runner isn't able to update state to Forgejo a job could be considered a zombie; this would trigger one of the codepaths where the job would be marked as failed.  If connectivity was later restored, then the runner could identify it was marked as failed and cancel the job context.  (This combination doesn't seem likely, but, I think it's reasonable to consider these failures as warnings because there may be unexpected errors here that we're not aware of).
```
time="2025-10-02T13:27:19-06:00" level=warning msg="ReportState error: unavailable: 502 Bad Gateway" func="[RunDaemon]" file="[reporter.go:207]"
```

Runner shutdown logging; just changed up to `Info` level:
```
time="2025-10-02T13:31:36-06:00" level=info msg="forcing the jobs to shutdown" func="[Shutdown]" file="[poller.go:93]"
[Test Action/job1]     Failure - Main sleep 120
[Test Action/job1] this step has been cancelled: ctx: context canceled, exec: RUN signal: killed
```

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- bug fixes
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1048): <!--number 1048 --><!--line 0 --><!--description Zml4OiBpbXByb3ZlIGxvZ2dpbmcgdG8gZGlhZ25vc2UgbXlzdGVyeSBqb2IgdGVybWluYXRpb25z-->fix: improve logging to diagnose mystery job terminations<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1048
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-10-02 22:43:50 +00:00
Mathieu Fenniak
d79d043696
fix: allow GC & cache operations to operate concurrently (#1040)
Fixes #1039.

Rather than opening and closing the Bolt DB instance constantly, the cache now maintains one open `*bolthold.Store` for its lifetime, allowing GC, cache read, and cache write operations to occur concurrently.

The major risk is this change is, "is it safe to use one Bolt instance across goroutines concurrently?"  [Bolt does document its concurrency requirements](https://github.com/boltdb/bolt?tab=readme-ov-file#transactions), and an analysis of our DB interactions looks to me like it introduces very little risk.

Most of the cache operations perform multiple touches to the database; for example `useCache` performs a read to fetch a cache object, and then an update to set its `UsedAt` timestamp.  If we wanted to ensure consistency in these operations, they should use a Bolt ReadWrite transaction -- but concurrent access would just be setting the field to the same value anyway.

The `gcCache` is the complex operation where a transaction might be warranted -- but doing so would also cause the same bug that #1039 indicates.  I believe it is safe to run without a transaction because it is protected by an application-level mutex (to prevent multiple concurrent GCs), it is the only code that performs deletes from the database -- these should guarantee that all its delete attempts are successful.  In the event of unexpected failure to do the DB write, `gcCache` deletes from the storage before deleting from the DB, so it should just attempt to cleanup again next run.

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- bug fixes
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1040): <!--number 1040 --><!--line 0 --><!--description Zml4OiBhbGxvdyBHQyAmIGNhY2hlIG9wZXJhdGlvbnMgdG8gb3BlcmF0ZSBjb25jdXJyZW50bHk=-->fix: allow GC & cache operations to operate concurrently<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1040
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-09-30 19:12:45 +00:00
Earl Warren
7f90c8acb2
fix: do not attempt to run the LXC stop script with self-hosted (#1037)
The test is covered by TestRunnerLXC which verifies the script actually runs on LXC.

Resolves forgejo/runner#1035

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- bug fixes
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1037): <!--number 1037 --><!--line 0 --><!--description Zml4OiBkbyBub3QgYXR0ZW1wdCB0byBydW4gdGhlIExYQyBzdG9wIHNjcmlwdCB3aXRoIHNlbGYtaG9zdGVk-->fix: do not attempt to run the LXC stop script with self-hosted<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1037
Reviewed-by: fnetX <fnetx@noreply.code.forgejo.org>
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.code.forgejo.org>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2025-09-28 14:49:45 +00:00
2franix
ea824bde1c
chore: test: exercise contexts in matrix when validating workflows (#1033)
After realizing my mistake on my proposed fixes in #1028, I figured I could at least propose another test covering the use of contexts in `jobs.<job-id>.strategy.matrix`.

The specification for available contexts is [here](https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#context-availability):

| Workflow key | Context |
| -------------------- | ----------- |
| `jobs.<job_id>.strategy` | `github`, `needs`, `vars`, `inputs` |

In Forgejo, the `forge` and `forgejo` contexts are supported in addition to `github`.

The new test covers a matrix with [`include`](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idstrategymatrixinclude), [`exclude`](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idstrategymatrixexclude) and custom properties. Both available and unavailable contexts are tested.

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- other
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1033): <!--number 1033 --><!--line 0 --><!--description Y2hvcmU6IHRlc3Q6IGV4ZXJjaXNlIGNvbnRleHRzIGluIG1hdHJpeCB3aGVuIHZhbGlkYXRpbmcgd29ya2Zsb3dz-->chore: test: exercise contexts in matrix when validating workflows<!--description-->
<!--end release-notes-assistant-->

Co-authored-by: 2franix <code@c.defx.fr>
Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1033
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: 2franix <2franix@noreply.code.forgejo.org>
Co-committed-by: 2franix <2franix@noreply.code.forgejo.org>
2025-09-28 07:15:51 +00:00
Mathieu Fenniak
56ef60060b
feat: support evaluating workflow-level concurrency blocks in jobparser (#1026)
- Changes `EvaluateConcurrency` to `EvaluateWorkflowConcurrency`, which has no job-related arguments
- Changes gitContext to be sent as an object rather than a map
- Allows `nil` to be returned for `cancelInProgress`, which indicates that the value wasn't specified in the input yaml -- required for distinguishing the `cancel-in-progress: false` case from not being specified at all.

ReadWorkflowRawConcurrency & EvaluateWorkflowConcurrency were never used in forgejo yet, so this shouldn't break the forgejo build.

Prerequisite for https://codeberg.org/forgejo/forgejo/pulls/9434.

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- features
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1026): <!--number 1026 --><!--line 0 --><!--description ZmVhdDogc3VwcG9ydCBldmFsdWF0aW5nIHdvcmtmbG93LWxldmVsIGNvbmN1cnJlbmN5IGJsb2NrcyBpbiBqb2JwYXJzZXI=-->feat: support evaluating workflow-level concurrency blocks in jobparser<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1026
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-09-27 04:37:36 +00:00
Kwonunn
6bdb7ed9c7
fix: Correctly override the value of Forgejo-Cache-Host when ACTIONS_CACHE_URL is overridden. (#1027)
This fixes a bug currently preventing use of an external cache server in the Codeberg runner setup.

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- bug fixes
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1027): <!--number 1027 --><!--line 0 --><!--description Zml4OiBDb3JyZWN0bHkgb3ZlcnJpZGUgdGhlIHZhbHVlIG9mIGBGb3JnZWpvLUNhY2hlLUhvc3RgIHdoZW4gQUNUSU9OU19DQUNIRV9VUkwgaXMgb3ZlcnJpZGRlbi4=-->fix: Correctly override the value of `Forgejo-Cache-Host` when ACTIONS_CACHE_URL is overridden.<!--description-->
<!--end release-notes-assistant-->

Co-authored-by: Vivian <me@vivstuff.gay>
Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1027
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.code.forgejo.org>
Co-authored-by: Kwonunn <kwonunn@noreply.code.forgejo.org>
Co-committed-by: Kwonunn <kwonunn@noreply.code.forgejo.org>
2025-09-26 07:02:45 +00:00
Earl Warren
ed7dcb0081
fix: a composite action must not change the result of the calling step before it completes (#1019)
Resolves forgejo/runner#1014

---

Manual testing can also be done using the [reproducer from the issue](https://code.forgejo.org/forgejo/runner/issues/1014#issuecomment-60694).

## Before

The first step of the local composite action sets the step result of the job to success which confuses Forgejo display.

![image](/attachments/4f5c9477-47b8-4450-a858-c86312ced946)

## After

Forgejo displays the progress of the composite action in the step calling it.

![image](/attachments/eed08b5d-b590-472f-9140-eced739dd47b)

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- bug fixes
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1019): <!--number 1019 --><!--line 0 --><!--description Zml4OiBhIGNvbXBvc2l0ZSBhY3Rpb24gbXVzdCBub3QgY2hhbmdlIHRoZSByZXN1bHQgb2YgdGhlIGNhbGxpbmcgc3RlcCBiZWZvcmUgaXQgY29tcGxldGVz-->fix: a composite action must not change the result of the calling step before it completes<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1019
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.code.forgejo.org>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2025-09-20 16:30:19 +00:00
Earl Warren
b8ab05e367
fix: schema validation must accept aliases and merges (#1012)
- aliases are an indirection to follow
  https://yaml.org/spec/1.2.1/#id2785586
- merges cannot be conveniently validated and are skipped
  https://yaml.org/type/merge.html

Resolves forgejo/runner#1011

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- bug fixes
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1012): <!--number 1012 --><!--line 0 --><!--description Zml4OiBzY2hlbWEgdmFsaWRhdGlvbiBtdXN0IGFjY2VwdCBhbGlhc2VzIGFuZCBtZXJnZXM=-->fix: schema validation must accept aliases and merges<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1012
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2025-09-18 07:19:44 +00:00
Earl Warren
e1e7d0e85a
fix: remove LXC working directory when it completes (#1003)
The working directory was not cleaned up upon completion of a LXC job because rc.stopJobContainer() -> rc.cleanUpJobContainer() -> rc.JobContainer.Remove() was never called for LXC containers.

- stopContainer() and closeContainer() must not call
  rc.stopHostEnvironment(ctx) for LXC containers because
  - it will needlessly be called twice
  - it intercepts the call to
    - rc.stopJobContainer()
    - rc.JobContainer.Close()
- rc.stopHostEnvironment(ctx) must be called in rc.cleanUpJobContainer which is indirectly called by rc.stopJobContainer()
- since rc.JobContainer.Close() is a noop, not calling it for LXC containers had no consequence

Resolves forgejo/runner#442

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- bug fixes
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/1003): <!--number 1003 --><!--line 0 --><!--description Zml4OiByZW1vdmUgTFhDIHdvcmtpbmcgZGlyZWN0b3J5IHdoZW4gaXQgY29tcGxldGVz-->fix: remove LXC working directory when it completes<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1003
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.code.forgejo.org>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2025-09-16 19:42:04 +00:00
Earl Warren
69df253e41
fix: ptyWriter.AutoStop is used by multiple goroutines
```
WARNING: DATA RACE
Write at 0x00c0008541d8 by goroutine 9324:
  code.forgejo.org/forgejo/runner/v11/act/container.(*HostEnvironment).exec()
      /home/debian/.cache/act/37b13738279f9342/hostexecutor/act/container/host_environment.go:368 +0x12dd
  code.forgejo.org/forgejo/runner/v11/act/runner.(*stepRun).main.func1.(*HostEnvironment).ExecWithCmdLine.1()
      /home/debian/.cache/act/37b13738279f9342/hostexecutor/act/container/host_environment.go:388
      +0x354

Previous read at 0x00c0008541d8 by goroutine 9328:
  code.forgejo.org/forgejo/runner/v11/act/container.(*ptyWriter).Write()
      /home/debian/.cache/act/37b13738279f9342/hostexecutor/act/container/host_environment.go:199 +0x57
  io.copyBuffer()
      /home/debian/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.7.linux-amd64/src/io/io.go:431
      +0x2ce

Goroutine 9324 (running) created at:
  code.forgejo.org/forgejo/runner/v11/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.2()
      /home/debian/.cache/act/37b13738279f9342/hostexecutor/act/common/executor.go:105 +0x144
  code.forgejo.org/forgejo/runner/v11/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.3.1()
      /home/debian/.cache/act/37b13738279f9342/hostexecutor/act/common/executor.go:107 +0x61
  code.forgejo.org/forgejo/runner/v11/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.3.gowrap1()
      /home/debian/.cache/act/37b13738279f9342/hostexecutor/act/common/executor.go:109 +0x4f
Goroutine 9328 (running) created at:
  code.forgejo.org/forgejo/runner/v11/act/container.(*HostEnvironment).exec()
      /home/debian/.cache/act/37b13738279f9342/hostexecutor/act/container/host_environment.go:356 +0x112a
  code.forgejo.org/forgejo/runner/v11/act/runner.(*stepRun).main.func1.(*HostEnvironment).ExecWithCmdLine.1()
      /home/debian/.cache/act/37b13738279f9342/hostexecutor/act/container/host_environment.go:388 +0x354
  code.forgejo.org/forgejo/runner/v11/act/runner.(*stepRun).main.func1()
```
2025-09-15 17:17:44 +02:00
Earl Warren
5c93da6fc7
feat: the forgejo context is equivalent to the github context (#999)
Resolves forgejo/runner#729

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- features
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/999): <!--number 999 --><!--line 0 --><!--description ZmVhdDogdGhlIGZvcmdlam8gY29udGV4dCBpcyBlcXVpdmFsZW50IHRvIHRoZSBnaXRodWIgY29udGV4dA==-->feat: the forgejo context is equivalent to the github context<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/999
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2025-09-15 09:14:11 +00:00
cascading-pr
543f3fd495
feat: add support for a trixie based Debian GNU/Linux backend (e.g. trixie-lxc:lxc://debian:trixie) (#997)
cascading-pr from https://code.forgejo.org/forgejo/lxc-helpers/pulls/35

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- features
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/997): <!--number 997 --><!--line 0 --><!--description ZmVhdDogYWRkIHN1cHBvcnQgZm9yIGEgdHJpeGllIGJhc2VkIERlYmlhbiBHTlUvTGludXggYmFja2VuZCAoZS5nLiB0cml4aWUtbHhjOmx4YzovL2RlYmlhbjp0cml4aWUp-->feat: add support for a trixie based Debian GNU/Linux backend (e.g. trixie-lxc:lxc://debian:trixie)<!--description-->
<!--end release-notes-assistant-->

Co-authored-by: cascading-pr <cascading-pr@example.com>
Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/997
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: cascading-pr <cascading-pr@noreply.code.forgejo.org>
Co-committed-by: cascading-pr <cascading-pr@noreply.code.forgejo.org>
2025-09-15 07:26:56 +00:00
Mathieu Fenniak
2573ccaf19
fix: send job outputs & job result to Forgejo in sync with each other (#995)
Fixes #994.

First commit ensures that the interpolateResults method is invoked before data is sent to the reporter.  Second commit changes how data is sent to the reporter to include both the result and the job outputs.

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- bug fixes
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/995): <!--number 995 --><!--line 0 --><!--description Zml4OiBzZW5kIGpvYiBvdXRwdXRzICYgam9iIHJlc3VsdCB0byBGb3JnZWpvIGluIHN5bmMgd2l0aCBlYWNoIG90aGVy-->fix: send job outputs & job result to Forgejo in sync with each other<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/995
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-09-14 20:02:43 +00:00
Earl Warren
02a51c0a21
fix: enforce job.<job-id>.timeout-minutes (#982)
- enforce timeout-minutes timeout for jobs in a way similar  to how it is done for steps
- minimal refactor of evaluateStepTimeout evaluateTimeout so it  can be used by jobs as well, with additional debug information  and error logging if parsing fails
- add integration tests for both step and job timeout-minutes,  verifying expressions are allowed and evaluated

Resolves forgejo/runner#979

---

Manually verified to work as expected https://v13.next.forgejo.org/earl-warren/testtimeout-minutes/actions/runs/3/jobs/0/attempt/1

```yaml
on: [push]
jobs:
  test:
    runs-on: docker
    timeout-minutes: 1
    steps:
      - run: |
          set -x
          while : ; do
            sleep 30
          done
```

![image](/attachments/047ddd15-7109-4931-a6ed-43073e4d31f9)

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- bug fixes
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/982): <!--number 982 --><!--line 0 --><!--description Zml4OiBlbmZvcmNlIGpvYi48am9iLWlkPi50aW1lb3V0LW1pbnV0ZXM=-->fix: enforce job.<job-id>.timeout-minutes<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/982
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.code.forgejo.org>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2025-09-11 14:43:26 +00:00
earl-warren
09adcc47d2
fix: shutdown the runner when the cache fails with a non recoverable error (#935)
Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/935
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.code.forgejo.org>
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
2025-09-07 16:03:31 +00:00
Earl Warren
4beb514232
fix: allow inputs context in action defaults (#941)
Resolves forgejo/runner#939

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- bug fixes
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/941): <!--number 941 --><!--line 0 --><!--description Zml4OiBhbGxvdyBpbnB1dHMgY29udGV4dCBpbiBhY3Rpb24gZGVmYXVsdHM=-->fix: allow inputs context in action defaults<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/941
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.code.forgejo.org>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2025-09-05 22:14:52 +00:00
Earl Warren
c7e2db2559
chore: cache: handler: test coverage for fatal errors 2025-09-05 17:30:08 +02:00
Earl Warren
5f0b036e34
chore: cache: move findCacheWithIsolationKeyFallback out of handler.find 2025-09-05 17:30:08 +02:00
Earl Warren
c48accfb51
chore: cache: generate mocks for act/artifactcache/caches.go 2025-09-05 17:30:08 +02:00
Earl Warren
c28a98082b
chore: cache: move repo != cache.Repo in readCache
- it only is used after calling readCache
- add unit test

it reduces the number of testcase to be considered in handler
2025-09-05 17:30:08 +02:00
Earl Warren
6c4e705f97
chore: cache: split caches implementation out of handler
- create the caches interface and matching cachesImpl
- move the cache logic out of handler
  - openDB
  - readCache
  - useCache
  - gcCache
  - access to the storage struct
    - serve
    - commit
    - exist
    - write
- add getCaches / setCaches to the handler interface so it can be
  used by tests. The caches test should be implemented independently
  in the future but this is a different kind of cleanup.
- no functional change, minimal refactor
2025-09-05 17:30:08 +02:00
Earl Warren
37f634fd31
fix: cache: call fatal() on errors that are not recoverable
- responseFatalJSON(w, r, err) replaces responseJSON(w, r, 500, err)
  and calls fatal() when the following fail because they are
  not recoverable. There may be other non-recoverable errors but
  it is difficult to be 100% sure they cannot be engineered by the
  caller of the API for DoS purposes.
  - openDB
  - findCache
  - cache.Repo != repo
- wrap errors in
  - openDB() - it was missing
  - readCache() - it was missing
  - useCache() - it was missing
  - findCache() - some had identical messages
- in gc
  - replace logger.Warnf with h.fatal
  - differentiate errors that have identical messages
  - call fatal if openDB fails instead of returning
2025-09-05 17:29:04 +02:00
Earl Warren
36ca627f2e
feat: cache: fatal() helper to gracefully terminate the runner
in case of an error that is not recoverable (e.g. failing to open the
bolthold database), the cache can call fatal() to log the error and
send a TERM signal that will gracefully shutdown the daemon.
2025-09-05 17:26:12 +02:00
Earl Warren
39dd708768
chore: cosmetic fixes 2025-09-05 13:22:59 +02:00
Earl Warren
8a7f760d3c
chore: bump version to v11 (#940)
the license change from MIT to GPLv3+ is a breaking change

Refs forgejo/runner#773

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- other
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/940): <!--number 940 --><!--line 0 --><!--description Y2hvcmU6IGJ1bXAgdmVyc2lvbiB0byB2MTE=-->chore: bump version to v11<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/940
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2025-09-05 07:29:38 +00:00
Mathieu Fenniak
a3aedba3f1
refactor: remove duplicate computeMac function (#936)
It was raised during embargo review of #925 that there are two implementations of `computeMac`; this PR fixes that.

As all the tests for `computeMac` were in the `artifactcache` package, it made more sense to keep the method there.  That required reversing the dependency `artifactcache->cacheproxy` package dependency -- it makes more sense to me for the proxy to depend on the cache, rather than vice-versa.

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- other
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/936): <!--number 936 --><!--line 0 --><!--description cmVmYWN0b3I6IHJlbW92ZSBkdXBsaWNhdGUgY29tcHV0ZU1hYyBmdW5jdGlvbg==-->refactor: remove duplicate computeMac function<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/936
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-09-05 06:01:49 +00:00
Earl Warren
69c6c70845
chore: refactor act/artifactcache Handler to an interface (#934)
- the Handler struct becomes handler (lowercase)
- the Handler interface is defined to be the existing methods
- isClosed() is added and used only in tests
- setgcAt() is added and used only in tests

---

This is to allow mocking the Handler interface for testing.

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- other
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/934): <!--number 934 --><!--line 0 --><!--description Y2hvcmU6IHJlZmFjdG9yIGFjdC9hcnRpZmFjdGNhY2hlIEhhbmRsZXIgdG8gYW4gaW50ZXJmYWNl-->chore: refactor act/artifactcache Handler to an interface<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/934
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.code.forgejo.org>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2025-09-04 14:38:50 +00:00
Earl Warren
aa428e375c
fix: an expression in with: for a reusable workflow call can use env (#931)
Resolves forgejo/runner#929

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- bug fixes
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/931): <!--number 931 --><!--line 0 --><!--description Zml4OiBhbiBleHByZXNzaW9uIGluIHdpdGg6IGZvciBhIHJldXNhYmxlIHdvcmtmbG93IGNhbGwgY2FuIHVzZSBlbnY=-->fix: an expression in with: for a reusable workflow call can use env<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/931
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2025-09-01 22:09:43 +00:00
earl-warren
57efbac055
fix(security): prevent on: pull_request actions from mutating caches of other workflow events (#925)
Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/925
2025-09-01 12:24:30 +00:00
Mathieu Fenniak
4bd93294d4
add WriteIsolationKey to MAC 2025-09-01 13:45:43 +02:00
Mathieu Fenniak
6c35ea4fd9
add unit tests for all changes in artifactcache 2025-09-01 13:45:43 +02:00
Mathieu Fenniak
da7ef7c2a1
fix: PRs cache artifacts separate from other runs 2025-09-01 13:45:43 +02:00
Earl Warren
11a96bb462
fix(security): ensure unique names for container images created by actions
Container images built by the runner are tagged with a unique name:

- based on the specified `uses` URL for remote actions.
- random for local actions.

In the case of local actions, this will create new tags for each run
but the images (and their layers) will be shared and not be
duplicated. The least recently used tags can be garbage collected by
tools such as https://github.com/stepchowfun/docuum.

Using a different method for creating the tag name for the remote
actions is to help with maintenance by establishing a direct relation
with the `uses` field. It was instead relying on a name transformed
multiple times which makes it more difficult to verify name collision
are not accidentally made possible by one of those transformations.

Without this fix, when a workflow ran a local [docker action](https://forgejo.org/docs/next/user/actions/actions/#docker-actions)
(e.g. the [example in the end-to-end
tests](8f920b4b7a/actions/example-force-rebuild/.forgejo/workflows/test.yml)),
it used an image tag that could collide with other workflows that
happen to use the same name.

The workaround for older runner versions is to set
[`[container].force_rebuild: true`](https://forgejo.org/docs/next/admin/actions/runner-installation/#configuration)
in the runner configuration file.
2025-09-01 13:41:06 +02:00
Earl Warren
7efe25f13d
chore: local action name collision regression tests
If the tag name collide (e.g. v9.1.1), it will fail with:

```
[push.yml/test] [DEBUG] Working directory '/home/earl-warren/software/runner/act/runner/testdata/local-action-dockerfile-tag/example2'
[push.yml/test]     Failure - Main [[ "example1 SOMEONE" == "example2 SOMEONE" ]]
```
2025-09-01 13:41:06 +02:00
Gusted
bbb2cdd9f7
chore: remove github.com/pkg/errors (#873)
The functionality provided by this package is also provided by the
standard library.

`fmt.Errorf` for dynamically generated errors.
`errors.new` for static errors.

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- other
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/873): <!--number 873 --><!--line 0 --><!--description Y2hvcmU6IHJlbW92ZSBgZ2l0aHViLmNvbS9wa2cvZXJyb3JzYA==-->chore: remove `github.com/pkg/errors`<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/873
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2025-08-28 09:33:52 +00:00
Earl Warren
579c5e24fc
chore: remove TestRunContext_GetGitHubContext (#900)
It does not assert anything useful and te associated function is otherwise heavily used in many tests. It may benefit from unit testing but this test would need to be done very differently to achieve that.

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- other
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/900): <!--number 900 --><!--line 0 --><!--description Y2hvcmU6IHJlbW92ZSBUZXN0UnVuQ29udGV4dF9HZXRHaXRIdWJDb250ZXh0-->chore: remove TestRunContext_GetGitHubContext<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/900
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2025-08-21 11:54:04 +00:00
Earl Warren
8f5470ad37
chore: replace gopkg.in/yaml.v3 with go.yaml.in/yaml/v3 (#888)
- gopkg.in/yaml.v3 is archived and unmaintained
- go.yaml.in/yaml/v3 is a compatible fork under the umbrella
  of https://yaml.org/

Refs https://code.forgejo.org/forgejo/runner/issues/887

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- other
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/888): <!--number 888 --><!--line 0 --><!--description V0lQOiBjaG9yZTogcmVwbGFjZSBnb3BrZy5pbi95YW1sLnYzIHdpdGggZ28ueWFtbC5pbi95YW1sL3Yz-->WIP: chore: replace gopkg.in/yaml.v3 with go.yaml.in/yaml/v3<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/888
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.code.forgejo.org>
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
2025-08-20 20:49:49 +00:00
Mathieu Fenniak
ce6502e7b6
chore: fix 'false positive' data race detection in Id/Number default init (#867)
A step's `Id` & `Number` are potentially initialized in different goroutines on matrix evaluations; this change ensures they're initialized before execution fans out to multiple goroutines.  There doesn't seem to be any functional impact of this data race for end-users.

Where `Number` was previously initialized, a runtime error was added to ensure that the behavior is the same.

`ID` data race:
```
==================
WARNING: DATA RACE
Read at 0x00c0001ff348 by goroutine 77:
  code.forgejo.org/forgejo/runner/v9/act/runner.newJobExecutor()
      /.../forgejo-runner/act/runner/job_executor.go:64 +0x424
  code.forgejo.org/forgejo/runner/v9/act/runner.(*RunContext).Executor()
      /.../forgejo-runner/act/runner/run_context.go:931 +0x2c6
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.1()
      /.../forgejo-runner/act/runner/runner.go:218 +0x150
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.2.1()
      /.../forgejo-runner/act/common/executor.go:107 +0x61
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.2.gowrap1()
      /.../forgejo-runner/act/common/executor.go:109 +0x4f

Previous write at 0x00c0001ff348 by goroutine 76:
  code.forgejo.org/forgejo/runner/v9/act/runner.newJobExecutor()
      /.../forgejo-runner/act/runner/job_executor.go:65 +0x4cc
  code.forgejo.org/forgejo/runner/v9/act/runner.(*RunContext).Executor()
      /.../forgejo-runner/act/runner/run_context.go:931 +0x2c6
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.1()
      /.../forgejo-runner/act/runner/runner.go:218 +0x150
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.2.1()
      /.../forgejo-runner/act/common/executor.go:107 +0x61
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.2.gowrap1()
      /.../forgejo-runner/act/common/executor.go:109 +0x4f

Goroutine 77 (running) created at:
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.2()
      /.../forgejo-runner/act/common/executor.go:105 +0x144
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.3.1()
      /.../forgejo-runner/act/common/executor.go:107 +0x61
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.3.gowrap1()
      /.../forgejo-runner/act/common/executor.go:109 +0x4f

Goroutine 76 (running) created at:
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.2()
      /.../forgejo-runner/act/common/executor.go:105 +0x144
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.3.1()
      /.../forgejo-runner/act/common/executor.go:107 +0x61
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.3.gowrap1()
      /.../forgejo-runner/act/common/executor.go:109 +0x4f
==================
```

`Number` data race:
```
==================
WARNING: DATA RACE
Write at 0x00c0001ff340 by goroutine 77:
  code.forgejo.org/forgejo/runner/v9/act/runner.newJobExecutor()
      /.../forgejo-runner/act/runner/job_executor.go:67 +0x536
  code.forgejo.org/forgejo/runner/v9/act/runner.(*RunContext).Executor()
      /.../forgejo-runner/act/runner/run_context.go:931 +0x2c6
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.1()
      /.../forgejo-runner/act/runner/runner.go:218 +0x150
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.2.1()
      /.../forgejo-runner/act/common/executor.go:107 +0x61
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.2.gowrap1()
      /.../forgejo-runner/act/common/executor.go:109 +0x4f

Previous write at 0x00c0001ff340 by goroutine 76:
  code.forgejo.org/forgejo/runner/v9/act/runner.newJobExecutor()
      /.../forgejo-runner/act/runner/job_executor.go:67 +0x536
  code.forgejo.org/forgejo/runner/v9/act/runner.(*RunContext).Executor()
      /.../forgejo-runner/act/runner/run_context.go:931 +0x2c6
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.1()
      /.../forgejo-runner/act/runner/runner.go:218 +0x150
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.2.1()
      /.../forgejo-runner/act/common/executor.go:107 +0x61
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.2.gowrap1()
      /.../forgejo-runner/act/common/executor.go:109 +0x4f

Goroutine 77 (running) created at:
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.2()
      /.../forgejo-runner/act/common/executor.go:105 +0x144
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.3.1()
      /.../forgejo-runner/act/common/executor.go:107 +0x61
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.3.gowrap1()
      /.../forgejo-runner/act/common/executor.go:109 +0x4f

Goroutine 76 (running) created at:
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.2()
      /.../forgejo-runner/act/common/executor.go:105 +0x144
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.3.1()
      /.../forgejo-runner/act/common/executor.go:107 +0x61
  code.forgejo.org/forgejo/runner/v9/act/runner.(*runnerImpl).NewPlanExecutor.func1.NewParallelExecutor.3.gowrap1()
      /.../forgejo-runner/act/common/executor.go:109 +0x4f
==================
```

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- other
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/867): <!--number 867 --><!--line 0 --><!--description Y2hvcmU6IGZpeCAnZmFsc2UgcG9zaXRpdmUnIGRhdGEgcmFjZSBkZXRlY3Rpb24gaW4gSWQvTnVtYmVyIGRlZmF1bHQgaW5pdA==-->chore: fix 'false positive' data race detection in Id/Number default init<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/867
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-08-20 19:56:03 +00:00
Mathieu Fenniak
fa42b8394e
chore: fix data race in reusable workflows with inherited secrets (#875)
Data race detection identified that `getWorkflowSecrets` is mutating `rc.caller.runContext.Config.Secrets` while interpolating values, in the case where secrets are inherited by a reusable workflow. This map is also mutated earlier in evaluation by `(*RunContext).handleCredentials`.  It's possible that multiple goroutines performing mutation to this shared map could cause runtime panics (not observed).

The issue is addressed creating a separate map to store interpolated secrets in `getWorkflowSecrets`, which was already the behavior in the non-inherited secret case.

Automated testing for this issue will be provided by #861 when all data races are resolved.

```
==================
WARNING: DATA RACE
Read at 0x00c0003a9620 by goroutine 2546:
  runtime.mapaccess1_faststr()
      /home/mfenniak/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.6.linux-amd64/src/internal/runtime/maps/runtime_faststr_swiss.go:103 +0x0
  code.forgejo.org/forgejo/runner/v9/act/runner.(*RunContext).handleCredentials()
      /.../forgejo-runner/act/runner/run_context.go:1395 +0xab
  code.forgejo.org/forgejo/runner/v9/act/runner.(*RunContext).prepareJobContainer()
      /.../forgejo-runner/act/runner/run_context.go:460 +0x2de
  code.forgejo.org/forgejo/runner/v9/act/runner.(*RunContext).startContainer.func1.(*RunContext).startJobContainer.2()
      /.../forgejo-runner/act/runner/run_context.go:610 +0x5e
  code.forgejo.org/forgejo/runner/v9/act/runner.(*RunContext).startContainer.func1()
      /.../forgejo-runner/act/runner/run_context.go:853 +0xf3
  code.forgejo.org/forgejo/runner/v9/act/runner.newJobExecutor.NewPipelineExecutor.Executor.Then.func22()
      /.../forgejo-runner/act/common/executor.go:136 +0x57
...snip...

Previous write at 0x00c0003a9620 by goroutine 2440:
  runtime.mapassign_faststr()
      /home/mfenniak/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.6.linux-amd64/src/internal/runtime/maps/runtime_faststr_swiss.go:263 +0x0
  code.forgejo.org/forgejo/runner/v9/act/runner.getWorkflowSecrets()
      /.../forgejo-runner/act/runner/expression.go:578 +0x547
  code.forgejo.org/forgejo/runner/v9/act/runner.(*RunContext).NewExpressionEvaluatorWithEnv()
      /.../forgejo-runner/act/runner/expression.go:85 +0x3fc
  code.forgejo.org/forgejo/runner/v9/act/common/git.FindGitRevision()
      /.../forgejo-runner/act/common/git/git.go:70 +0xe4
  github.com/go-git/go-git/v5.PlainOpenWithOptions()
      /home/mfenniak/go/pkg/mod/github.com/go-git/go-git/v5@v5.16.2/repository.go:332 +0x7a6
  code.forgejo.org/forgejo/runner/v9/act/common/git.FindGitRevision()
      /.../forgejo-runner/act/common/git/git.go:58 +0xc4
...snip...
==================
```

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/875
Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-08-20 13:34:57 +00:00
Mathieu Fenniak
022d5ad3e7
fix: artifact cache DB not using indexes for searching (#878)
Uses the `Repo` field as an index during searches of the cache database.  Removes unused indexes.

To measure the performance of this change, I created a synthetic test which wrote 10,000 records into the artifact cache DB.  Of course, all benchmarks are lies that can't be generalized to real-world usage, but it seems clear from the magnitude of improvement that this fixes a flawed implementation, even if it's not perfect.
- Unmodified performance:
    - Write: 196 records/second
    - Read: 1 record/second
- With `Repo` index being used for reads, and other indexes being removed:
    - Write: 347 records/second
    - Read: 22,398 records/second

`Repo` is, I think, the only index that made sense to remain, with an eye on workflow run performance:
- `Key` -- can't be used for index because `findCache` searches for key *prefixes*, not equal values.
- `Version` -- isn't very distinct for different workflow runs (https://code.forgejo.org/actions/cache#cache-version)
- `Complete` - significant portion of the cache DB will be complete, making it the least selective possible index
- `UsedAt` & `CreatedAt` - only used in GC operation, so could remain, but this isn't a performance-sensitive codepath

Closes #874.

<!--start release-notes-assistant-->
<!--URL:https://code.forgejo.org/forgejo/runner-->
- bug fixes
  - [PR](https://code.forgejo.org/forgejo/runner/pulls/878): <!--number 878 --><!--line 0 --><!--description Zml4OiBhcnRpZmFjdCBjYWNoZSBEQiBub3QgdXNpbmcgaW5kZXhlcyBmb3Igc2VhcmNoaW5n-->fix: artifact cache DB not using indexes for searching<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/878
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2025-08-19 20:19:23 +00:00