6 Commits
fix-sec ... ldc

Author SHA1 Message Date
ldc_
c7dfd1c149 feat: add Dockerfile.custom for Debian-based runner image 2026-02-02 15:32:18 +08:00
ldc_
9d0b60643c debug: add logging for containerOptions auto-addition 2026-02-02 15:31:44 +08:00
dcsunny
8fab783aa9 feat(cache): 实现缓存服务器host.docker.internal支持和配置自动检测
- 在缓存服务器启动时自动将外部URL转换为host.docker.internal格式
- 添加useHostDockerInternal字段用于标识是否使用host.docker.internal映射
- 自动向容器选项添加--add-host=host.docker.internal:host-gateway参数
- 实现配置文件自动检测功能,当未指定配置文件时默认查找config.yaml
- 在cmd.go中添加PersistentPreRunE钩子函数进行配置文件预处理
- 添加调试输出语句用于跟踪缓存服务器启动流程
2026-02-02 14:28:02 +08:00
dcsunny
f1a473b362 chore(build): 配置 Go 模块代理并移除工作流文件
- 在 Dockerfile 中设置默认 GOPROXY 为阿里云镜像
- 在 Makefile 中配置 GOPROXY 环境变量
- 移除 .gitea/workflows 目录下的所有 CI/CD 工作流文件
- 删除 release-nightly.yml 工作流配置
- 删除 release-tag.yml 工作流配置
- 删除 test.yml 工作流配置
2026-01-30 11:35:52 +08:00
mkesper
90d11b8692 Remove duplicate assignment of DIST (#777)
The assignment already happens at line 1.

Signed-off-by: mkesper <mkesper@noreply.gitea.com>

Reviewed-on: https://gitea.com/gitea/act_runner/pulls/777
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: mkesper <mkesper@noreply.gitea.com>
Co-committed-by: mkesper <mkesper@noreply.gitea.com>
2025-12-26 00:38:38 +00:00
Christopher Homberger
c4b57fbcb2 chore(deps): upgrade dependencies (#775)
CI uses latest go 24, we may need a cron job after go updates.

Closes https://gitea.com/gitea/act_runner/issues/774

Reviewed-on: https://gitea.com/gitea/act_runner/pulls/775
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Christopher Homberger <christopher.homberger@web.de>
Co-committed-by: Christopher Homberger <christopher.homberger@web.de>
2025-12-20 23:35:15 +00:00
9 changed files with 70 additions and 228 deletions

View File

@@ -1,85 +0,0 @@
---
name: release-nightly
on:
workflow_dispatch:
push:
branches:
- 'main'
tags:
- '*'
env:
DOCKER_ORG: gitea
DOCKER_LATEST: nightly
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-go@v5
with:
go-version-file: "go.mod"
- name: goreleaser
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser-pro
args: release --nightly
env:
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
S3_REGION: ${{ secrets.AWS_REGION }}
S3_BUCKET: ${{ secrets.AWS_BUCKET }}
GORELEASER_FORCE_TOKEN: "gitea"
GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }}
release-image:
runs-on: ubuntu-latest
strategy:
matrix:
variant:
- target: basic
tag_suffix: ""
- target: dind
tag_suffix: "-dind"
- target: dind-rootless
tag_suffix: "-dind-rootless"
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0 # all history for all branches and tags
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker BuildX
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Echo the tag
run: echo "${{ env.DOCKER_ORG }}/act_runner:nightly${{ matrix.variant.tag_suffix }}"
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
target: ${{ matrix.variant.target }}
platforms: |
linux/amd64
linux/arm64
push: true
tags: |
${{ env.DOCKER_ORG }}/act_runner:nightly${{ matrix.variant.tag_suffix }}

View File

@@ -1,111 +0,0 @@
name: release-tag
on:
push:
tags:
- "*"
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # all history for all branches and tags
- uses: actions/setup-go@v5
with:
go-version-file: "go.mod"
- name: Import GPG key
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.PASSPHRASE }}
fingerprint: CC64B1DB67ABBEECAB24B6455FC346329753F4B0
- name: goreleaser
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser-pro
args: release
env:
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
S3_REGION: ${{ secrets.AWS_REGION }}
S3_BUCKET: ${{ secrets.AWS_BUCKET }}
GORELEASER_FORCE_TOKEN: "gitea"
GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
release-image:
runs-on: ubuntu-latest
container:
image: catthehacker/ubuntu:act-latest
env:
DOCKER_ORG: gitea
DOCKER_LATEST: latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # all history for all branches and tags
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker BuildX
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Get Meta
id: meta
run: |
echo REPO_NAME=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $2}') >> $GITHUB_OUTPUT
echo REPO_VERSION=${GITHUB_REF_NAME#v} >> $GITHUB_OUTPUT
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
target: basic
platforms: |
linux/amd64
linux/arm64
push: true
tags: |
${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.REPO_VERSION }}
${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ env.DOCKER_LATEST }}
- name: Build and push dind
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
target: dind
platforms: |
linux/amd64
linux/arm64
push: true
tags: |
${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.REPO_VERSION }}-dind
${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ env.DOCKER_LATEST }}-dind
- name: Build and push dind-rootless
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
target: dind-rootless
platforms: |
linux/amd64
linux/arm64
push: true
tags: |
${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.REPO_VERSION }}-dind-rootless
${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ env.DOCKER_LATEST }}-dind-rootless

View File

@@ -1,20 +0,0 @@
name: checks
on:
- push
- pull_request
jobs:
lint:
name: check and test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- name: vet checks
run: make vet
- name: build
run: make build
- name: test
run: make test

View File

@@ -7,7 +7,7 @@ FROM golang:1.24-alpine AS builder
RUN apk add --no-cache make git
ARG GOPROXY
ENV GOPROXY=${GOPROXY:-}
ENV GOPROXY=${GOPROXY:-https://mirrors.aliyun.com/goproxy/,direct}
COPY . /opt/src/act_runner
WORKDIR /opt/src/act_runner

17
Dockerfile.custom Normal file
View File

@@ -0,0 +1,17 @@
FROM debian:bookworm-slim
# 安装必要的工具
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl git && rm -rf /var/lib/apt/lists/*
# 复制自定义编译的 act_runner
# 注意:构建前需要先确保当前目录下有编译好的 act_runner 二进制文件
COPY act_runner /usr/local/bin/act_runner
RUN chmod +x /usr/local/bin/act_runner
# 创建数据目录
RUN mkdir -p /data/cache
WORKDIR /data
ENTRYPOINT ["/usr/local/bin/act_runner"]
CMD ["daemon", "--config", "/config.yaml"]

View File

@@ -1,7 +1,6 @@
DIST := dist
EXECUTABLE := act_runner
GOFMT ?= gofumpt -l
DIST := dist
DIST_DIRS := $(DIST)/binaries $(DIST)/release
GO ?= go
SHASUM ?= shasum -a 256
@@ -22,6 +21,8 @@ DOCKER_REF := $(DOCKER_IMAGE):$(DOCKER_TAG)
DOCKER_ROOTLESS_REF := $(DOCKER_IMAGE):$(DOCKER_TAG)-dind-rootless
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1
GOPROXY ?= https://mirrors.aliyun.com/goproxy/,direct
export GOPROXY
ifneq ($(shell uname), Darwin)
EXTLDFLAGS = -extldflags "-static" $(null)

View File

@@ -24,11 +24,12 @@ type cacheServerArgs struct {
func runCacheServer(ctx context.Context, configFile *string, cacheArgs *cacheServerArgs) func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
fmt.Println("cache1")
cfg, err := config.LoadDefault(*configFile)
if err != nil {
return fmt.Errorf("invalid configuration: %w", err)
}
fmt.Println("cache2")
initLogging(cfg)
var (
@@ -47,7 +48,7 @@ func runCacheServer(ctx context.Context, configFile *string, cacheArgs *cacheSer
if cacheArgs.Port != 0 {
port = cacheArgs.Port
}
fmt.Println("cache2")
cacheHandler, err := artifactcache.StartHandler(
dir,
host,

View File

@@ -15,6 +15,8 @@ import (
)
func Execute(ctx context.Context) {
configFile := ""
// ./act_runner
rootCmd := &cobra.Command{
Use: "act_runner [event name to run]\nIf no event name passed, will default to \"on: push\"",
@@ -22,8 +24,16 @@ func Execute(ctx context.Context) {
Args: cobra.MaximumNArgs(1),
Version: ver.Version(),
SilenceUsage: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
// Auto-detect config.yaml if not specified
if configFile == "" {
if _, err := os.Stat("config.yaml"); err == nil {
configFile = "config.yaml"
}
}
return nil
},
}
configFile := ""
rootCmd.PersistentFlags().StringVarP(&configFile, "config", "c", "", "Config file path")
// ./act_runner register

View File

@@ -7,6 +7,7 @@ import (
"context"
"encoding/json"
"fmt"
"net/url"
"path/filepath"
"strings"
"sync"
@@ -38,6 +39,8 @@ type Runner struct {
labels labels.Labels
envs map[string]string
useHostDockerInternal bool
runningTasks sync.Map
}
@@ -52,9 +55,14 @@ func NewRunner(cfg *config.Config, reg *config.Registration, cli client.Client)
for k, v := range cfg.Runner.Envs {
envs[k] = v
}
// Setup cache
useHostDockerInternal := false
if cfg.Cache.Enabled == nil || *cfg.Cache.Enabled {
if cfg.Cache.ExternalServer != "" {
envs["ACTIONS_CACHE_URL"] = cfg.Cache.ExternalServer
if strings.Contains(cfg.Cache.ExternalServer, "host.docker.internal") {
useHostDockerInternal = true
}
} else {
cacheHandler, err := artifactcache.StartHandler(
cfg.Cache.Dir,
@@ -66,7 +74,16 @@ func NewRunner(cfg *config.Config, reg *config.Registration, cli client.Client)
log.Errorf("cannot init cache server, it will be disabled: %v", err)
// go on
} else {
envs["ACTIONS_CACHE_URL"] = cacheHandler.ExternalURL() + "/"
// Use host.docker.internal for container access
externalURL := cacheHandler.ExternalURL()
if parsedURL, err := url.Parse(externalURL); err == nil {
parsedURL.Host = "host.docker.internal:" + parsedURL.Port()
envs["ACTIONS_CACHE_URL"] = parsedURL.String() + "/"
} else {
envs["ACTIONS_CACHE_URL"] = externalURL + "/"
}
useHostDockerInternal = true
log.Infof("Cache server started at %s, using host.docker.internal for container access", externalURL)
}
}
}
@@ -81,11 +98,12 @@ func NewRunner(cfg *config.Config, reg *config.Registration, cli client.Client)
envs["GITEA_ACTIONS_RUNNER_VERSION"] = ver.Version()
return &Runner{
name: reg.Name,
cfg: cfg,
client: cli,
labels: ls,
envs: envs,
name: reg.Name,
cfg: cfg,
client: cli,
labels: ls,
envs: envs,
useHostDockerInternal: useHostDockerInternal,
}
}
@@ -197,6 +215,17 @@ func (r *Runner) run(ctx context.Context, task *runnerv1.Task, reporter *report.
maxLifetime = time.Until(deadline)
}
// Auto-add host.docker.internal if cache is enabled
containerOptions := r.cfg.Container.Options
if r.useHostDockerInternal {
if containerOptions == "" {
containerOptions = "--add-host=host.docker.internal:host-gateway"
} else if !strings.Contains(containerOptions, "--add-host=host.docker.internal") {
containerOptions += " --add-host=host.docker.internal:host-gateway"
}
log.Infof("Auto-added host.docker.internal mapping for cache: %s", containerOptions)
}
runnerConfig := &runner.Config{
// On Linux, Workdir will be like "/<parent_directory>/<owner>/<repo>"
// On Windows, Workdir will be like "\<parent_directory>\<owner>\<repo>"
@@ -219,7 +248,7 @@ func (r *Runner) run(ctx context.Context, task *runnerv1.Task, reporter *report.
ContainerNamePrefix: fmt.Sprintf("GITEA-ACTIONS-TASK-%d", task.Id),
ContainerMaxLifetime: maxLifetime,
ContainerNetworkMode: container.NetworkMode(r.cfg.Container.Network),
ContainerOptions: r.cfg.Container.Options,
ContainerOptions: containerOptions,
ContainerDaemonSocket: r.cfg.Container.DockerHost,
Privileged: r.cfg.Container.Privileged,
DefaultActionInstance: r.getDefaultActionsURL(ctx, task),