## Background
`DOCKER_USERNAME` and `DOCKER_PASSWORD` are commonly used by workflows as ordinary secrets for logging in to a private registry and pushing images. However, the runner also treated these secret names as implicit Docker pull credentials.
These credentials carry no registry information, but they were attached to every pull unconditionally. As a result, a user who configured `DOCKER_USERNAME` / `DOCKER_PASSWORD` secrets for their private registry (e.g. to push images) would have those same credentials sent to Docker Hub when pulling a public image, causing the pull to fail with authentication failure.
## Changes
- Stop using `DOCKER_USERNAME` and `DOCKER_PASSWORD` as implicit pull credentials for job containers.
- Stop injecting `DOCKER_USERNAME` and `DOCKER_PASSWORD` as pull credentials for step containers.
## ⚠️ BREAKING ⚠️
This is a breaking change.
Workflows or runner setups that previously relied on `DOCKER_USERNAME` and `DOCKER_PASSWORD` being implicitly used for Docker image pulls must migrate to an explicit authentication mechanism.
Migration options:
- For private job container images, use `container.credentials`:
```yaml
jobs:
build:
container:
image: registry.example.com/image:tag
credentials:
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
```
- For private service container images, use service `credentials`.
- For private `uses: docker://...` or private Docker actions, configure Docker authentication in the runner environment before the job starts. For example, run `docker login` on the runner host.
`DOCKER_USERNAME` and `DOCKER_PASSWORD` can still be used as ordinary workflow secrets, for example with `docker/login-action` before pushing images.
---
Related:
- Fixes#386
---------
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-on: https://gitea.com/gitea/runner/pulls/1007
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Zettat123 <39446+zettat123@noreply.gitea.com>
Co-committed-by: Zettat123 <39446+zettat123@noreply.gitea.com>
`NewGitCloneExecutor` holds a per-directory mutex while it `git checkout --force`s a remote action into the shared `<ActionCacheDir>/<UsesHash>`, but four read sites ran unlocked:
- `maybeCopyToActionDir`'s tar walk via `JobContainer.CopyDir`
- `prepareActionExecutor`'s `readAction` parse of `action.yml`
- `newReusableWorkflowExecutor`'s `model.NewWorkflowPlanner` after `cloneRemoteReusableWorkflow` released its lock
- `execAsDocker` when `ActionCache == nil`: `docker build` walks `contextDir` for the daemon-side build context
When two matrix jobs share a `uses:`, a read interleaved with a peer's checkout produces partial state — observed as `Cannot find module .../dist/index.js` and `setup-uv` failing on a half-written `action.yml`.
Exports `acquireCloneLock` as `AcquireCloneLock` and takes it at all four sites. `container.ImageExistsLocally` / `NewDockerBuildExecutor` and `model.NewWorkflowPlanner` are indirected through package-level vars so the docker-action build path and the reusable-workflow read site are testable without a real daemon, mirroring `ContainerNewContainer`. Three regression tests cover the higher-risk sites (`maybeCopyToActionDir`, `execAsDocker`, `newReusableWorkflowExecutor`); each fails if its `AcquireCloneLock` is removed.
Subsumed by https://gitea.com/gitea/runner/pulls/814 once that lands. Related: https://gitea.com/gitea/runner/pulls/930
---
This PR was written with the help of Claude Opus 4.7
---------
Co-authored-by: Nicolas <bircni@icloud.com>
Reviewed-on: https://gitea.com/gitea/runner/pulls/938
Reviewed-by: Nicolas <bircni@icloud.com>
Reviewed-by: Zettat123 <39446+zettat123@noreply.gitea.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-committed-by: silverwind <me@silverwind.io>
Removes 88 `nolint` directives (386 → 298) via mechanical, zero-regression cleanups:
- **38 `bodyclose`** in `act/artifactcache/handler_test.go`: replaced by `defer resp.Body.Close()` after each HTTP call.
- **21 dead directives** (`gocyclo`, `dogsled`, `contextcheck`): none of these linters are enabled in `.golangci.yml`, so the directives were doing nothing.
- **29 `testifylint`** directives whose underlying issues were addressed by mechanical rewrites:
- `assert.Nil(t, err)` → `assert.NoError(t, err)`
- `assert.NotNil(t, err)` → `assert.Error(t, err)`
- `assert.Equal(t, true/false, x)` → `assert.True/False(t, x)`
- `assert.Equal(t, 0, len(x))` → `assert.Empty(t, x)`
- `assert.Equal(t, N, len(x))` → `assert.Len(t, x, N)`
- `assert.Len(t, x, 0)` → `assert.Empty(t, x)`
Many `testifylint` directives still apply because they flag `require-error` (i.e. testifylint wants `require.NoError` instead of `assert.NoError` for early bail-out). That's a behavior change (fail-fast vs continue) and out of scope for this purely mechanical cleanup — those can be addressed in a follow-up. Same for `expected-actual`, `equal-values`, `error-is-as`, and the remaining `nilnil` / `unparam` / `forbidigo` / `staticcheck` / `goheader` / `dupl` directives.
`golangci-lint run` is clean. Tests pass for all touched packages.
---
This PR was written with the help of Claude Opus 4.7
Reviewed-on: https://gitea.com/gitea/act_runner/pulls/864
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: silverwind <2021+silverwind@noreply.gitea.com>
Co-committed-by: silverwind <2021+silverwind@noreply.gitea.com>
Merges the `gitea.com/gitea/act` fork into this repository as the `act/`
directory and consumes it as a local package. The `replace github.com/nektos/act
=> gitea.com/gitea/act` directive is removed; act's dependencies are merged
into the root `go.mod`.
- Imports rewritten: `github.com/nektos/act/pkg/...` → `gitea.com/gitea/act_runner/act/...`
(flattened — `pkg/` boundary dropped to match the layout forgejo-runner adopted).
- Dropped act's CLI (`cmd/`, `main.go`) and all upstream project files; kept
the library tree + `LICENSE`.
- Added `// Copyright <year> The Gitea Authors ...` / `// Copyright <year> nektos`
headers to 104 `.go` files.
- Pre-existing act lint violations annotated inline with
`//nolint:<linter> // pre-existing issue from nektos/act`.
`.golangci.yml` is unchanged vs `main`.
- Makefile test target: `-race -short` (matches forgejo-runner).
- Pre-existing integration test failures fixed: race in parallel executor
(atomic counters); TestSetupEnv / command_test / expression_test /
run_context_test updated to match gitea fork runtime; TestJobExecutor and
TestActionCache gated on `testing.Short()`.
Full `gitea/act` commit history is reachable via the second parent.
Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>