Commit Graph
12 Commits
Author SHA1 Message Date
Nicolasandsilverwind 0b9f251b6a fix: deliver cancel ack and reap leftover Windows job processes (#996)
## Summary

- When Gitea cancels a job, the reporter cancels its own task context; the final Close() flush then aborted on that same cancelled context and Gitea never received the runner's acknowledgement (missing tail logs and final state).
- On Windows the cancelled context also neutralised terminateRunningProcesses, leaving step grandchildren alive in the workspace, holding file handles, so the runner could no longer clean up and pick up new work.
- Reporter.Close() now flushes on a detached, bounded context via a new rpcCtx() helper and configurable Runner.ReportCloseTimeout (default 10s).
- terminateRunningProcesses now PowerShell-enumerates Win32_Process and taskkill /T /F's every process whose ExecutablePath or CommandLine references the job's workspace directories, on a detached context.
- The daemon heartbeat loop still exits on <-r.ctx.Done(): the runner is intentionally seen as offline by Gitea during cleanup so it isn't handed a new task overlapping the in-progress teardown.

## Test plan

- [x] go test ./internal/pkg/report/... ./act/container/ -run 'TestReporter_ServerCancelStillFlushesFinal|TestBuildWindowsWorkspaceKillScript'
- [x] make fmt && make lint-go - 0 issues
- [x] GOOS=windows go build ./... - clean
- [x] Manual on a Windows runner: trigger a long-running workflow, cancel from Gitea UI; verify (a) the job ends with tail logs + cancelled state in Gitea, (b) workspace cleans up, (c) the runner picks up a new job without restart.

Authored-by: bircni
🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: silverwind <[email protected]>
Reviewed-on: https://gitea.com/gitea/runner/pulls/996
Reviewed-by: silverwind <[email protected]>
2026-05-24 10:01:01 +00:00
Nicolas 273f6b4247 fix(reporter): respect configured log level for job log forwarding (#989)
## Summary

- Non-raw_output log entries above the globally configured `log.level` are no longer forwarded to the Gitea job log output
- Step output (`raw_output=true`) is always forwarded regardless of level — it is actual job stdout/stderr, not runner internals
- State-machine fields (`stepResult`, `jobResult`) are always processed regardless of level, preserving correct tracking for skipped steps (whose `stepResult` is emitted at `DebugLevel` in `step.go`)
- Extracts a `shouldAppendLogRow` helper to avoid repeating the combined `!duringSteps() && entry.Level <= log.GetLevel()` guard in three places

## Why not the approach in #677

PR #677 adds `if entry.Level != log.GetLevel() { return nil }` at the top of `Fire()`. That has two bugs:
1. Uses `!=` instead of `>`, so `Error`/`Fatal` entries are dropped when the configured level is `Warn`
2. Returns early before processing `stepResult`/`jobResult` state fields — skipped steps (whose `stepResult` is logged at `DebugLevel`) would never be marked complete

This fix instead applies the level guard only at the `r.logRows` append sites, leaving state tracking unconditional.

Relates to #409.

Reviewed-on: https://gitea.com/gitea/runner/pulls/989
Reviewed-by: Lunny Xiao <[email protected]>
2026-05-23 17:28:44 +00:00
Nicolas d6fbe75721 ci: add PR title linting against Conventional Commits (#988)
Lint PR titles

Reviewed-on: https://gitea.com/gitea/runner/pulls/988
Reviewed-by: Lunny Xiao <[email protected]>
2026-05-21 19:13:43 +00:00
NicolasandLunny Xiao 4317662a38 update docker cli to v29.5.2 (#984)
Fixes #981

Reviewed-on: https://gitea.com/gitea/runner/pulls/984
Reviewed-by: Zettat123 <[email protected]>
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: Nicolas <[email protected]>
Co-committed-by: Nicolas <[email protected]>
2026-05-20 20:25:44 +00:00
6023928876 Fix token use with schemaless Gitea instance (#977)
Fixes #973

## Summary
- Normalize schemaless `--gitea-instance` values before comparing clone URL hosts
- Add regression tests for `GITEA_TOKEN` use with private action/reusable workflow clones on the same instance

---------

Co-authored-by: silverwind <[email protected]>
Co-authored-by: silverwind <[email protected]>
Reviewed-on: https://gitea.com/gitea/runner/pulls/977
Reviewed-by: Lunny Xiao <[email protected]>
Reviewed-by: silverwind <[email protected]>
Co-authored-by: Nicolas <[email protected]>
Co-committed-by: Nicolas <[email protected]>
2026-05-18 02:22:04 +00:00
Nicolasandsilverwind 8a99506fed Fix host cleanup, volume allowlist, cache upload, and action host edge cases (#970)
## Summary
- prevent host-mode execution from deleting caller-owned workdirs
- harden `valid_volumes` checks against `..` and symlink escapes
- return immediately after artifact cache upload write failures
- default implicit remote action clone hosts to `GitHubInstance`/`github.com`

Authored with assistance from OpenAI Codex GPT-5.

---------

Co-authored-by: silverwind <[email protected]>
Reviewed-on: https://gitea.com/gitea/runner/pulls/970
Reviewed-by: silverwind <[email protected]>
2026-05-17 12:53:04 +00:00
3ea7d39690 fix: overwrite read-only files when copying action directories (#942)
## Summary

  - `CopyCollector.WriteFile` now removes any existing destination file
    before writing, handling read-only modes (e.g. git pack files at
    `0444`) that cause `EACCES`/`ERROR_ACCESS_DENIED` on macOS and Windows.
  - Added `O_TRUNC` to the `OpenFile` flags as a safety net.

  ## Root cause

  When a composite action with a post step runs on a host runner,
  `runPostStep` calls `maybeCopyToActionDir`, which re-copies the action
  into `miscpath/act/actions/<name>/`. The first copy (main step) writes
  `.git/objects/pack/*.idx` at the destination with mode `0444` (as set
  by go-git). The second copy (post step) calls
  `os.OpenFile(dest, O_CREATE|O_WRONLY, …)` on that existing `0444` file,
  which fails immediately:

  - macOS: `open <path>: permission denied`
  - Windows: `open <path>: Access is denied`

Fixes: https://gitea.com/gitea/runner/issues/941
Fixes: https://gitea.com/gitea/runner/issues/876

---------

Co-authored-by: silverwind <[email protected]>
Co-authored-by: silverwind <[email protected]>
Reviewed-on: https://gitea.com/gitea/runner/pulls/942
Reviewed-by: silverwind <[email protected]>
Co-authored-by: Nicolas <[email protected]>
Co-committed-by: Nicolas <[email protected]>
2026-05-08 04:11:42 +00:00
Nicolasandsilverwind 2a4d56c650 feat: add startup janitor for stale bind-workdir task workspaces (#870)
- Add idle-time cleanup for stale bind-workdir task directories instead of cleaning them on the task execution path.
- Make cleanup behavior configurable with `runner.startup_cleanup_age` as the stale-age threshold (default: `24h`) and `runner.idle_cleanup_interval` as the idle cleanup cadence (default: `10m`).
- Restrict cleanup scope to numeric task directory names only, to avoid touching operator-managed folders.
- Document the cleanup settings in `config.example.yaml` and `README.md`.
- Add tests for stale-directory cleanup, idle cleanup throttling, and config default/override parsing.

## Why

When a runner or host crashes, normal per-task cleanup may not run, leaving stale task directories under the bind-workdir root. Running this cleanup only while the runner is idle recovers that disk space without adding overhead to active job execution.

If you want, I can also tighten the wording around `startup_cleanup_age`, since the key name now reads a bit misleadingly relative to the actual behavior.

---------

Co-authored-by: silverwind <[email protected]>
Reviewed-on: https://gitea.com/gitea/runner/pulls/870
Reviewed-by: silverwind <[email protected]>
2026-05-05 20:11:44 +00:00
a22119cf88 fix(host): correct host workspace cleanup on Windows (#883)
## Summary
- Fix host-mode cleanup to remove the job **workspace** directory after a run (instead of leaving checkouts behind).
- On Windows, track step process PIDs and terminate remaining process trees during teardown before attempting workspace deletion (prevents file-lock failures).
- Skip workspace deletion when `bind_workdir` is enabled to avoid conflicting with runner-level task directory cleanup.

## Implementation details
- `HostEnvironment` now records PIDs for started commands and best-effort terminates them on Windows during `Remove()`.
- Workspace removal uses a small retry loop on Windows to handle transient locks.
- `BindWorkdir` is propagated into `HostEnvironment` so cleanup behavior matches runner configuration.

---------

Co-authored-by: silverwind <[email protected]>
Co-authored-by: silverwind <[email protected]>
Reviewed-on: https://gitea.com/gitea/runner/pulls/883
Reviewed-by: silverwind <[email protected]>
2026-05-05 18:28:12 +00:00
NicolasandLunny Xiao c45a4e6d32 ci: Fix triggers (#882)
Currently on a branch a workflow got triggered 2x one time on push and one time as its a PR
Now it only gets triggered on PR and on push onto main

Reviewed-on: https://gitea.com/gitea/runner/pulls/882
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: Nicolas <[email protected]>
Co-committed-by: Nicolas <[email protected]>
2026-05-01 16:37:37 +00:00
NicolasandLunny Xiao 8e6b3be96a docs: Update docs (#872)
Co-authored-by: Lunny Xiao <[email protected]>
Reviewed-on: https://gitea.com/gitea/act_runner/pulls/872
Reviewed-by: Lunny Xiao <[email protected]>
Co-authored-by: Nicolas <[email protected]>
Co-committed-by: Nicolas <[email protected]>
2026-04-30 18:29:59 +00:00
547a0ff297 feat: show run command, shell and env in collapsible group before step output (#847)
## Summary

Mirrors the GitHub Actions runner behaviour where each `run:` step shows a collapsible **"Run \<command\>"** section containing the script, shell command, and environment variables before the actual step output.

### What changes

- **`pkg/runner/step_run.go`**: In `stepRun.main()`, two new executors are added to the pipeline:
  1. `logRunGroupHeader()` — runs after `setupShellCommandExecutor()` (so `sr.cmdline` is already resolved). Emits a `::group::Run <step>` log entry followed by the interpolated script, the full shell command line, and the step's env vars (sorted, internal vars filtered out).
  2. The existing execution function now has `defer rawLogger.Infof("::endgroup::")` so the group is closed after the step finishes, regardless of success or failure.

### Env var filtering

Internal runner vars are hidden (`GITHUB_*`, `GITEA_*`, `RUNNER_*`, `INPUT_*`, `PATH`, `HOME`) — only user-relevant vars are shown, matching what GitHub Actions displays.

### Example output

```
▼ Run cargo build
  cargo build
  shell: bash --noprofile --norc -e -o pipefail {0}
  env:
    CARGO_HOME: /home/runner/.cargo
    CARGO_INCREMENTAL: 0
    CARGO_TERM_COLOR: always
  <actual build output>
```

---------

Co-authored-by: silverwind <[email protected]>
Co-authored-by: silverwind <[email protected]>
Reviewed-on: https://gitea.com/gitea/act_runner/pulls/847
Reviewed-by: silverwind <[email protected]>
Reviewed-by: ChristopherHX <[email protected]>
2026-04-27 16:31:56 +00:00