Compare commits

...

11 commits
main ... v2.1.0

Author SHA1 Message Date
Earl Warren
5e04df7cb4
[FORGEJO] include ACT at the desired version 2023-07-02 14:51:16 +02:00
Earl Warren
48e2029726
[FORGEJO] no double / in WorkDir, it would fail local actions 2023-07-02 14:51:16 +02:00
Earl Warren
29df0337a6
[FORGEJO] default labels to a single docker 2023-07-02 14:51:16 +02:00
Earl Warren
3911e2aaba
[FORGEJO] branding 2023-07-02 14:51:16 +02:00
Earl Warren
9eb3aac405
[FORGEJO] README.md 2023-07-02 14:51:16 +02:00
Earl Warren
21d1f3ec88
[FORGEJO] upgrade alpine 3.18 2023-07-02 14:51:16 +02:00
Earl Warren
80fa6c470d
[FORGEJO] workflows 2023-07-02 14:51:16 +02:00
Earl Warren
cc2f3f9e48
[FORGEJO] look for workflows in the .forgejo/workflows directory 2023-07-02 14:51:16 +02:00
Earl Warren
c0090363c0
[FORGEJO] GITHUB_SERVER_URL is always the runner registration addr 2023-07-02 14:51:16 +02:00
Earl Warren
0e11fb42b7
[FORGEJO] build forgejo-runner 2023-07-02 14:51:16 +02:00
Earl Warren
fc3375a5b1
[FORGEJO] delete files conflicting with Forgejo 2023-07-02 14:51:10 +02:00
23 changed files with 430 additions and 486 deletions

2
.dockerignore Normal file
View file

@ -0,0 +1,2 @@
Dockerfile
forgejo-runner

View file

@ -0,0 +1,133 @@
name: Build release
on:
push:
tags: 'v*'
jobs:
release:
runs-on: self-hosted
# root is used for testing, allow it
if: github.repository_owner == 'forgejo-integration' || github.repository_owner == 'root'
steps:
- uses: actions/checkout@v3
- id: verbose
run: |
# if there are no secrets, be verbose
if test -z "${{ secrets.TOKEN }}"; then
value=true
else
value=false
fi
echo "value=$value" >> "$GITHUB_OUTPUT"
echo "shell=set -x" >> "$GITHUB_OUTPUT"
- id: registry
run: |
${{ steps.verbose.outputs.shell }}
url="${{ env.GITHUB_SERVER_URL }}"
hostport=${url##http*://}
hostport=${hostport%%/}
echo "host-port=${hostport}" >> "$GITHUB_OUTPUT"
if ! [[ $url =~ ^http:// ]] ; then
exit 0
fi
cat >> "$GITHUB_OUTPUT" <<EOF
insecure=true
buildx-config<<ENDVAR
[registry."${hostport}"]
http = true
ENDVAR
EOF
- id: secrets
run: |
token="${{ secrets.TOKEN }}"
doer="${{ secrets.DOER }}"
if test -z "$token"; then
apt-get -qq install -y jq
doer=root
api=http://$doer:admin1234@${{ steps.registry.outputs.host-port }}/api/v1/users/$doer/tokens
curl -sS -X DELETE $api/release
token=$(curl -sS -X POST -H 'Content-Type: application/json' --data-raw '{"name": "release", "scopes": ["all"]}' $api | jq --raw-output .sha1)
fi
echo "token=${token}" >> "$GITHUB_OUTPUT"
echo "doer=${doer}" >> "$GITHUB_OUTPUT"
- name: allow docker pull/push to forgejo
if: ${{ steps.registry.outputs.insecure }}
run: |-
mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
"insecure-registries" : ["${{ steps.registry.outputs.host-port }}"],
"bip": "172.26.0.1/16"
}
EOF
- run: |
echo deb http://deb.debian.org/debian bullseye-backports main | tee /etc/apt/sources.list.d/backports.list && apt-get -qq update
DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -qq -y -t bullseye-backports docker.io
- uses: https://github.com/docker/setup-buildx-action@v2
with:
config-inline: |
${{ steps.registry.outputs.buildx-config }}
- run: |
token="${{ steps.secrets.outputs.token }}" ; test -z "$token" && token="${{ secrets.TOKEN }}"
doer="${{ steps.secrets.outputs.doer }}" ; test -z "$doer" && doer="${{ secrets.DOER }}"
BASE64_AUTH=`echo -n "$doer:$token" | base64`
mkdir -p ~/.docker
echo "{\"auths\": {\"$CI_REGISTRY\": {\"auth\": \"$BASE64_AUTH\"}}}" > ~/.docker/config.json
env:
CI_REGISTRY: "${{ env.GITHUB_SERVER_URL }}${{ env.GITHUB_REPOSITORY_OWNER }}"
- id: build
run: |
${{ steps.verbose.outputs.shell }}
tag="${{ github.ref_name }}"
tag=${tag##*v}
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "image=${{ steps.registry.outputs.host-port }}/${{ github.repository }}:${tag}" >> "$GITHUB_OUTPUT"
- uses: https://github.com/docker/build-push-action@v4
# workaround until https://github.com/docker/build-push-action/commit/d8823bfaed2a82c6f5d4799a2f8e86173c461aba is in @v4 or @v5 is released
env:
ACTIONS_RUNTIME_TOKEN: ''
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.build.outputs.image }}
- run: |
${{ steps.verbose.outputs.shell }}
mkdir -p release
for arch in amd64 arm64; do
docker create --platform linux/$arch --name runner ${{ steps.build.outputs.image }}
docker cp runner:/bin/forgejo-runner release/forgejo-runner-$arch
shasum -a 256 < release/forgejo-runner-$arch | cut -f1 -d ' ' > release/forgejo-runner-$arch.sha256
docker rm runner
done
- name: publish release (when TOKEN secret is NOT set)
if: ${{ secrets.TOKEN == '' }}
uses: https://code.forgejo.org/actions/forgejo-release@v1
with:
direction: upload
release-dir: release
release-notes: "RELEASE-NOTES#${{ steps.build.outputs.tag }}"
token: ${{ steps.secrets.outputs.token }}
verbose: ${{ steps.verbose.outputs.value }}
- name: publish release (when TOKEN secret is set)
if: ${{ secrets.TOKEN != '' }}
uses: https://code.forgejo.org/actions/forgejo-release@v1
with:
direction: upload
release-dir: release
release-notes: "RELEASE-NOTES#${{ steps.build.outputs.tag }}"
token: ${{ secrets.TOKEN }}
verbose: ${{ steps.verbose.outputs.value }}

View file

@ -0,0 +1,59 @@
name: Integration tests for the release process
on:
push:
paths:
- go.mod
- Dockerfile
- .forgejo/workflows/release.yml
- .forgejo/workflows/integration.yml
jobs:
release-simulation:
runs-on: self-hosted
if: github.repository_owner != 'forgejo-integration' && github.repository_owner != 'forgejo-experimental' && github.repository_owner != 'forgejo-release'
steps:
- uses: actions/checkout@v3
- id: forgejo
uses: https://code.forgejo.org/actions/setup-forgejo@v1
with:
user: root
password: admin1234
image-version: 1.19
lxc-ip-prefix: 10.0.9
- name: publish the runner release
run: |
set -x
dir=$(mktemp -d)
trap "rm -fr $dir" EXIT
url=http://root:admin1234@${{ steps.forgejo.outputs.host-port }}
export FORGEJO_RUNNER_LOGS="${{ steps.forgejo.outputs.runner-logs }}"
#
# Create a new project with the runner and the release workflow only
#
rsync -a --exclude .git ./ $dir/
rm $(find $dir/.forgejo/workflows/*.yml | grep -v release.yml)
forgejo-test-helper.sh push $dir $url root runner |& tee $dir/pushed
eval $(grep '^sha=' < $dir/pushed)
#
# Push a tag to trigger the release workflow and wait for it to complete
#
forgejo-test-helper.sh api POST $url repos/root/runner/tags ${{ steps.forgejo.outputs.token }} --data-raw '{"tag_name": "v1.2.3", "target": "'$sha'"}'
LOOPS=180 forgejo-test-helper.sh wait_success "$url" root/runner $sha
#
# Minimal sanity checks. e2e test is for the setup-forgejo action
# and the infrastructure playbook.
#
curl -L -sS $url/root/runner/releases/download/v1.2.3/forgejo-runner-amd64 > forgejo-runner
chmod +x forgejo-runner
./forgejo-runner --version | grep 1.2.3
curl -L -sS $url/root/runner/releases/download/v1.2.3/forgejo-runner-amd64.sha256 > forgejo-runner.one
shasum -a 256 < forgejo-runner | cut -f1 -d ' ' > forgejo-runner.two
diff forgejo-runner.one forgejo-runner.two

View file

@ -0,0 +1,40 @@
name: Publish release
on:
push:
tags: 'v*'
jobs:
release:
runs-on: self-hosted
if: github.repository_owner == 'forgejo-release' && secrets.TOKEN != ''
steps:
- name: install the certificate authority
run: |
apt-get install -qq -y wget
wget --no-check-certificate -O /usr/local/share/ca-certificates/enough.crt https://forgejo.octopuce.forgejo.org/forgejo/enough/raw/branch/main/certs/2023-05-13/ca.crt
update-ca-certificates --fresh
- uses: actions/checkout@v3
- name: download release
uses: https://code.forgejo.org/actions/forgejo-release@v1
with:
url: https://code.forgejo.org
repo: forgejo-integration/runner
direction: download
release-dir: release
download-retry: 60
token: ${{ secrets.TOKEN }}
- name: upload release
uses: https://code.forgejo.org/actions/forgejo-release@v1
with:
url: https://code.forgejo.org
repo: forgejo/runner
direction: upload
release-dir: release
release-notes: "RELEASE-NOTES"
token: ${{ secrets.TOKEN }}
gpg-private-key: ${{ secrets.GPG }}

View file

@ -0,0 +1,43 @@
# SPDX-License-Identifier: MIT
name: copy container images from integration to the destination organization
on:
push:
tags: 'v*'
jobs:
builder:
runs-on: self-hosted
if: github.repository_owner == 'forgejo-release' && secrets.TOKEN != ''
steps:
- name: apt-get install docker.io
run: |
DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -qq -y docker.io
- name: login code.forgejo.org
uses: https://github.com/docker/login-action@v2
with:
registry: code.forgejo.org
username: ${{ secrets.DOER }}
password: ${{ secrets.TOKEN }}
- id: tag
run: |
tag="${{ github.ref_name }}"
tag=${tag##*v}
echo "tag=$tag" >> "$GITHUB_OUTPUT"
- uses: https://code.forgejo.org/forgejo/forgejo-container-image@v1
env:
VERIFY: 'false'
with:
url: https://code.forgejo.org
destination-owner: forgejo
owner: forgejo-integration
suffixes: ' '
project: runner
tag: ${{ steps.tag.outputs.tag }}
doer: ${{ secrets.DOER }}
token: ${{ secrets.TOKEN }}
verbose: true

View file

@ -0,0 +1,24 @@
name: checks
on:
- pull_request
- push
env:
GOPROXY: https://goproxy.io,direct
jobs:
lint:
name: check and test
if: github.repository_owner != 'forgejo-integration' && github.repository_owner != 'forgejo-experimental' && github.repository_owner != 'forgejo-release'
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v3
with:
go-version: 1.20
- uses: actions/checkout@v3
- name: vet checks
run: make vet
- name: build
run: make build
- name: test
run: make test

View file

@ -1,105 +0,0 @@
name: release-nightly
on:
push:
branches: [ main ]
env:
GOPATH: /go_path
GOCACHE: /go_cache
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # all history for all branches and tags
- uses: actions/setup-go@v3
with:
go-version: '>=1.20.1'
- uses: https://gitea.com/actions/go-hashfiles@v0.0.1
id: hash-go
with:
patterns: |
go.mod
go.sum
- name: cache go
id: cache-go
uses: https://github.com/actions/cache@v3
with:
path: |
/go_path
/go_cache
key: go_path-${{ steps.hash-go.outputs.hash }}
- name: goreleaser
uses: https://github.com/goreleaser/goreleaser-action@v4
with:
distribution: goreleaser-pro
version: latest
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 }}
release-image:
runs-on: ubuntu-latest
container:
image: catthehacker/ubuntu:act-latest
env:
DOCKER_ORG: gitea
DOCKER_LATEST: nightly
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0 # all history for all branches and tags
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker BuildX
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
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=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT
- name: Build and push
uses: docker/build-push-action@v4
env:
ACTIONS_RUNTIME_TOKEN: '' # See https://gitea.com/gitea/act_runner/issues/119
with:
context: .
file: ./Dockerfile
platforms: |
linux/amd64
linux/arm64
push: true
tags: |
${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ env.DOCKER_LATEST }}
- name: Build and push dind-rootless
uses: docker/build-push-action@v4
env:
ACTIONS_RUNTIME_TOKEN: '' # See https://gitea.com/gitea/act_runner/issues/119
with:
context: .
file: ./Dockerfile.rootless
platforms: |
linux/amd64
linux/arm64
push: true
tags: |
${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ env.DOCKER_LATEST }}-dind-rootless

View file

@ -1,118 +0,0 @@
name: release-tag
on:
push:
tags:
- '*'
env:
GOPATH: /go_path
GOCACHE: /go_cache
jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # all history for all branches and tags
- uses: actions/setup-go@v3
with:
go-version: '>=1.20.1'
- uses: https://gitea.com/actions/go-hashfiles@v0.0.1
id: hash-go
with:
patterns: |
go.mod
go.sum
- name: cache go
id: cache-go
uses: https://github.com/actions/cache@v3
with:
path: |
/go_path
/go_cache
key: go_path-${{ steps.hash-go.outputs.hash }}
- name: Import GPG key
id: import_gpg
uses: https://github.com/crazy-max/ghaction-import-gpg@v5
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.PASSPHRASE }}
fingerprint: CC64B1DB67ABBEECAB24B6455FC346329753F4B0
- name: goreleaser
uses: https://github.com/goreleaser/goreleaser-action@v4
with:
distribution: goreleaser-pro
version: latest
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@v3
with:
fetch-depth: 0 # all history for all branches and tags
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker BuildX
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
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=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT
- name: Build and push
uses: docker/build-push-action@v4
env:
ACTIONS_RUNTIME_TOKEN: '' # See https://gitea.com/gitea/act_runner/issues/119
with:
context: .
file: ./Dockerfile
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-rootless
uses: docker/build-push-action@v4
env:
ACTIONS_RUNTIME_TOKEN: '' # See https://gitea.com/gitea/act_runner/issues/119
with:
context: .
file: ./Dockerfile.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,38 +0,0 @@
name: checks
on:
- push
- pull_request
env:
GOPATH: /go_path
GOCACHE: /go_cache
jobs:
lint:
name: check and test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: '>=1.20.1'
- uses: https://gitea.com/actions/go-hashfiles@v0.0.1
id: hash-go
with:
patterns: |
go.mod
go.sum
- name: cache go
id: cache-go
uses: https://github.com/actions/cache@v3
with:
path: |
/go_path
/go_cache
key: go_path-${{ steps.hash-go.outputs.hash }}
- name: vet checks
run: make vet
- name: build
run: make build
- name: test
run: make test

4
.gitignore vendored
View file

@ -1,4 +1,6 @@
act_runner
*~
forgejo-runner
.env
.runner
coverage.txt

View file

@ -1,12 +0,0 @@
#!/bin/bash
set -e
if [ -z "$1" ]; then
echo "usage: $0 <path>"
exit 1
fi
SUM=$(shasum -a 256 "$1" | cut -d' ' -f1)
BASENAME=$(basename "$1")
echo -n "${SUM} ${BASENAME}" > "$1".sha256

View file

@ -1,115 +0,0 @@
before:
hooks:
- go mod tidy
builds:
- env:
- CGO_ENABLED=0
goos:
- darwin
- linux
- windows
- freebsd
goarch:
- amd64
- arm
- arm64
goarm:
- "5"
- "6"
- "7"
ignore:
- goos: darwin
goarch: arm
- goos: darwin
goarch: ppc64le
- goos: darwin
goarch: s390x
- goos: windows
goarch: ppc64le
- goos: windows
goarch: s390x
- goos: windows
goarch: arm
goarm: "5"
- goos: windows
goarch: arm
goarm: "6"
- goos: windows
goarch: arm
goarm: "7"
- goos: windows
goarch: arm64
- goos: freebsd
goarch: ppc64le
- goos: freebsd
goarch: s390x
- goos: freebsd
goarch: arm
goarm: "5"
- goos: freebsd
goarch: arm
goarm: "6"
- goos: freebsd
goarch: arm
goarm: "7"
- goos: freebsd
goarch: arm64
flags:
- -trimpath
ldflags:
- -s -w -X gitea.com/gitea/act_runner/internal/pkg/ver.version={{ .Summary }}
binary: >-
{{ .ProjectName }}-
{{- .Version }}-
{{- .Os }}-
{{- if eq .Arch "amd64" }}amd64
{{- else if eq .Arch "amd64_v1" }}amd64
{{- else if eq .Arch "386" }}386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}-{{ .Arm }}{{ end }}
no_unique_dist_dir: true
hooks:
post:
- cmd: xz -k -9 {{ .Path }}
dir: ./dist/
- cmd: sh .goreleaser.checksum.sh {{ .Path }}
- cmd: sh .goreleaser.checksum.sh {{ .Path }}.xz
blobs:
-
provider: s3
bucket: "{{ .Env.S3_BUCKET }}"
region: "{{ .Env.S3_REGION }}"
folder: "act_runner/{{.Version}}"
extra_files:
- glob: ./**.xz
- glob: ./**.sha256
archives:
- format: binary
name_template: "{{ .Binary }}"
allow_different_binary_count: true
checksum:
name_template: 'checksums.txt'
extra_files:
- glob: ./**.xz
snapshot:
name_template: "{{ .Branch }}-devel"
nightly:
name_template: "nightly"
gitea_urls:
api: https://gitea.com/api/v1
download: https://gitea.com
release:
extra_files:
- glob: ./**.xz
- glob: ./**.xz.sha256
# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj

View file

@ -1,16 +1,15 @@
FROM golang:1.20-alpine3.18 as builder
# Do not remove `git` here, it is required for getting runner version when executing `make build`
RUN apk add --no-cache make git
#Build stage
FROM golang:1.20-alpine3.18 AS build-env
COPY . /opt/src/act_runner
WORKDIR /opt/src/act_runner
RUN apk --no-cache add build-base git
RUN make clean && make build
COPY . /srv
WORKDIR /srv
RUN make build
FROM alpine:3.18
RUN apk add --no-cache git bash tini
LABEL maintainer="contact@forgejo.org"
COPY --from=builder /opt/src/act_runner/act_runner /usr/local/bin/act_runner
COPY scripts/run.sh /opt/act/run.sh
COPY --from=build-env /srv/forgejo-runner /bin/forgejo-runner
ENTRYPOINT ["/sbin/tini","--","/opt/act/run.sh"]
ENTRYPOINT ["/bin/forgejo-runner"]

View file

@ -1,3 +1,4 @@
Copyright (c) 2023 The Forgejo Authors
Copyright (c) 2022 The Gitea Authors
Permission is hereby granted, free of charge, to any person obtaining a copy

View file

@ -1,5 +1,5 @@
DIST := dist
EXECUTABLE := act_runner
EXECUTABLE := forgejo-runner
GOFMT ?= gofumpt -l
DIST := dist
DIST_DIRS := $(DIST)/binaries $(DIST)/release
@ -21,11 +21,7 @@ DOCKER_TAG ?= nightly
DOCKER_REF := $(DOCKER_IMAGE):$(DOCKER_TAG)
DOCKER_ROOTLESS_REF := $(DOCKER_IMAGE):$(DOCKER_TAG)-dind-rootless
ifneq ($(shell uname), Darwin)
EXTLDFLAGS = -extldflags "-static" $(null)
else
EXTLDFLAGS =
endif
EXTLDFLAGS = -extldflags "-static" $(null)
ifeq ($(HAS_GO), GO)
GOPATH ?= $(shell $(GO) env GOPATH)
@ -117,7 +113,7 @@ install: $(GOFILES)
build: go-check $(EXECUTABLE)
$(EXECUTABLE): $(GOFILES)
$(GO) build -v -tags '$(TAGS)' -ldflags '$(EXTLDFLAGS)-s -w $(LDFLAGS)' -o $@
$(GO) build -v -tags 'netgo osusergo $(TAGS)' -ldflags '$(EXTLDFLAGS)-s -w $(LDFLAGS)' -o $@
.PHONY: deps-backend
deps-backend:

141
README.md
View file

@ -1,93 +1,122 @@
# act runner
# Forgejo Runner
Act runner is a runner for Gitea based on [Gitea fork](https://gitea.com/gitea/act) of [act](https://github.com/nektos/act).
A daemon that connects to a Forgejo instance and runs jobs for continous integration. The high level [installation instructions](https://forgejo.org/docs/next/admin/actions/) are part of the Forgejo documentation.
## Installation
# Configuration
### Prerequisites
Display the usage with `forgejo-runner --help`.
Docker Engine Community version is required for docker mode. To install Docker CE, follow the official [install instructions](https://docs.docker.com/engine/install/).
For more information on the configuration file, see the [commented example](internal/pkg/config/config.example.yaml).
### Download pre-built binary
# Hacking
Visit [here](https://dl.gitea.com/act_runner/) and download the right version for your platform.
The Forgejo runner depends on [a fork of ACT](https://code.forgejo.org/forgejo/act) and is a dependency of the [setup-forgejo action](https://code.forgejo.org/actions/setup-forgejo). Together they provide a development environment with end to end testing. Each repository also has some unit testing that can be used to quickly detect the simplest mistakes such as a failure to compile or static code checking failures (vulnerability, lint, etc.).
### Build from source
Assuming the modifications to the [Forgejo runner](https://code.forgejo.org/forgejo/runner) are pushed to a fork in a branch named `wip-runner-change`, a pull request will verify it compiles and the binary is sane (running `forgejo-runner --version`). It will not verify that it is able to properly run jobs when connected to a live Forgejo instance.
```bash
make build
For end to end testing, a branch should be pushed to a fork of the [setup-forgejo action](https://code.forgejo.org/actions/setup-forgejo) with a [modification to the tests](https://code.forgejo.org/actions/setup-forgejo/src/commit/ae7f03683b7b05c7d9c6aaeacaf27843de0366a4/.forgejo/workflows/integration.yml#L10-L19), similar to:
```yaml
#
# Uncomment the following for a shortcut to debugging the Forgejo runner.
# It will build the runner from a designated repository and branch instead of
# downloading it from a canonical release.
#
./forgejo-test-helper.sh build_runner https://code.forgejo.org/earl-warren/runner wip-runner-change
```
### Build a docker image
Where https://code.forgejo.org/earl-warren/runner is the URL of the Forgejo runner fork and `wip-runner-change` is the branch where the changes under test were pushed. When they do the `setup-forgejo` branch can be discarded.
```bash
make docker
The runner can be released by merging the `wip-runner-change` branch and by pushing a new tag, for instance `v10.2.3`. Once published, the `setup-forgejo` action can be updated to default to this latest version knowing it already passed integration tests.
## ACT
Assuming the modifications to [ACT](https://code.forgejo.org/forgejo/act) are pushed to a fork in a branch named `wip-act-change`, a pull request will verify it compiles. It will not verify that the Forgejo runner can compile with it.
For verifying it is compatible with the Forgejo runner, a branch should be pushed to a fork of the [Forgejo runner](https://code.forgejo.org/forgejo/runner) (for instance `wip-runner-change`) that uses the ACT version under test in the `wip-act-change` by modifying `go.mod` to contain something like the following and running `go mod tidy`:
```
replace github.com/nektos/act => code.forgejo.org/earl-warren/act wip-act-change
```
## Quickstart
Where https://code.forgejo.org/earl-warren/act is the URL of the act fork and `wip-act-change` is the branch where the changes under test were pushed. It will not verify that it is able to properly run jobs when connected to a live Forgejo instance. The `wip-runner-change` branch must, in turn, be tested as explained above. When the Forgejo runner modified to include the changes in the `wip-act-change` branch pass the end to end test of the `setup-forgejo` action, it is ready to be released.
### Register
ACT can be released by merging the `wip-act-change` branch and by pushing a new tag, for instance `v48.8.20`. Once published, the Forgejo runner can be updated to default to this latest version knowing it already passed end to end tests with something like:
```bash
./act_runner register
```
replace github.com/nektos/act => code.forgejo.org/forgejo/act v48.8.20
```
And you will be asked to input:
## Local debug
1. Gitea instance URL, like `http://192.168.8.8:3000/`. You should use your gitea instance ROOT_URL as the instance argument
and you should not use `localhost` or `127.0.0.1` as instance IP;
2. Runner token, you can get it from `http://192.168.8.8:3000/admin/runners`;
3. Runner name, you can just leave it blank;
4. Runner labels, you can just leave it blank.
The repositories are checked out in the same directory:
The process looks like:
- **runner**: [Forgejo runner](https://code.forgejo.org/forgejo/runner)
- **act**: [ACT](https://code.forgejo.org/forgejo/act)
- **setup-forgejo**: [setup-forgejo](https://code.forgejo.org/actions/setup-forgejo)
```text
INFO Registering runner, arch=amd64, os=darwin, version=0.1.5.
WARN Runner in user-mode.
INFO Enter the Gitea instance URL (for example, https://gitea.com/):
http://192.168.8.8:3000/
INFO Enter the runner token:
fe884e8027dc292970d4e0303fe82b14xxxxxxxx
INFO Enter the runner name (if set empty, use hostname: Test.local):
### Install dependencies
INFO Enter the runner labels, leave blank to use the default labels (comma-separated, for example, ubuntu-20.04:docker://node:16-bullseye,ubuntu-18.04:docker://node:16-buster,linux_arm:host):
The dependencies are installed manually or with:
INFO Registering runner, name=Test.local, instance=http://192.168.8.8:3000/, labels=[ubuntu-latest:docker://node:16-bullseye ubuntu-22.04:docker://node:16-bullseye ubuntu-20.04:docker://node:16-bullseye ubuntu-18.04:docker://node:16-buster].
DEBU Successfully pinged the Gitea instance server
INFO Runner registered successfully.
```shell
setup-forgejo/forgejo-dependencies.sh
```
You can also register with command line arguments.
### Build the Forgejo runner with the local ACT
```bash
./act_runner register --instance http://192.168.8.8:3000 --token <my_runner_token> --no-interactive
The Forgejo runner is rebuilt with the ACT directory by changing the `runner/go.mod` file to:
```
replace github.com/nektos/act => ../act
```
If the registry succeed, it will run immediately. Next time, you could run the runner directly.
Running:
### Run
```bash
./act_runner daemon
```
cd runner ; go mod tidy
```
### Configuration
Building:
You can also configure the runner with a configuration file.
The configuration file is a YAML file, you can generate a sample configuration file with `./act_runner generate-config`.
```bash
./act_runner generate-config > config.yaml
```shell
cd runner ; rm -f forgejo-runner ; make forgejo-runner
```
You can specify the configuration file path with `-c`/`--config` argument.
### Run Forgejo and the runner
```bash
./act_runner -c config.yaml register # register with config file
./act_runner -c config.yaml daemon # run with config file
A Forgejo instance is launched with:
```shell
cd setup-forgejo ; ./forgejo.sh setup
firefox http://$(cat forgejo-ip):3000
```
### Example Deployments
The user is `root` with password `admin1234`. The runner is registered with:
Check out the [examples](examples) directory for sample deployment types.
```
cd setup-forgejo
docker exec --user 1000 forgejo forgejo actions generate-runner-token > forgejo-runner-token
../runner/forgejo-runner register --no-interactive --instance "http://$(cat forgejo-ip):3000/" --name runner --token $(cat forgejo-runner-token) --labels docker:docker://node:16-bullseye,self-hosted
```
And launched in debug mode with:
```shell
cd setup-forgejo ; ACTIONS_STEP_DEBUG=true ../runner/forgejo-runner daemon
```
### Try a sample workflow
From the Forgejo web interface, create a repository and add the following to `.forgejo/workflows/try.yaml`. It will launch the job and the result can be observed from the `actions` tab.
```yaml
on: [push]
jobs:
ls:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: |
ls ${{ github.workspace }}
```

2
go.mod
View file

@ -89,4 +89,4 @@ require (
gopkg.in/yaml.v2 v2.4.0 // indirect
)
replace github.com/nektos/act => gitea.com/gitea/act v0.246.1
replace github.com/nektos/act => code.forgejo.org/forgejo/act v1.7.0

4
go.sum
View file

@ -1,9 +1,9 @@
code.forgejo.org/forgejo/act v1.7.0 h1:BQA0jPla4khQFcNCI2Bbr+qK9PsRE1DFtG/YXSrhARU=
code.forgejo.org/forgejo/act v1.7.0/go.mod h1:oU/5klyP5O+J2psPS3t50t09+SNVg+fZ/jN4lDZAq1U=
code.gitea.io/actions-proto-go v0.3.0 h1:9Tvg8+TaaCXPKi6EnWl9vVgs2VZsj1Cs5afnsHa4AmM=
code.gitea.io/actions-proto-go v0.3.0/go.mod h1:00ys5QDo1iHN1tHNvvddAcy2W/g+425hQya1cCSvq9A=
code.gitea.io/gitea-vet v0.2.3-0.20230113022436-2b1561217fa5 h1:daBEK2GQeqGikJESctP5Cu1i33z5ztAD4kyQWiw185M=
code.gitea.io/gitea-vet v0.2.3-0.20230113022436-2b1561217fa5/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE=
gitea.com/gitea/act v0.246.1 h1:/HGPW/VqpvlDYgnCQNp1/cIPKwEhiwpYxx4r+xrUwIk=
gitea.com/gitea/act v0.246.1/go.mod h1:oU/5klyP5O+J2psPS3t50t09+SNVg+fZ/jN4lDZAq1U=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=

View file

@ -17,8 +17,8 @@ import (
func Execute(ctx context.Context) {
// ./act_runner
rootCmd := &cobra.Command{
Use: "act_runner [event name to run]\nIf no event name passed, will default to \"on: push\"",
Short: "Run GitHub actions locally by specifying the event name (e.g. `push`) or an action name directly.",
Use: "forgejo-runner [event name to run]\nIf no event name passed, will default to \"on: push\"",
Short: "Run Forgejo Actions locally by specifying the event name (e.g. `push`) or an action name directly.",
Args: cobra.MaximumNArgs(1),
Version: ver.Version(),
SilenceUsage: true,
@ -35,7 +35,7 @@ func Execute(ctx context.Context) {
RunE: runRegister(ctx, &regArgs, &configFile), // must use a pointer to regArgs
}
registerCmd.Flags().BoolVar(&regArgs.NoInteractive, "no-interactive", false, "Disable interactive mode")
registerCmd.Flags().StringVar(&regArgs.InstanceAddr, "instance", "", "Gitea instance address")
registerCmd.Flags().StringVar(&regArgs.InstanceAddr, "instance", "", "Forgejo instance address")
registerCmd.Flags().StringVar(&regArgs.Token, "token", "", "Runner token")
registerCmd.Flags().StringVar(&regArgs.RunnerName, "name", "", "Runner name")
registerCmd.Flags().StringVar(&regArgs.Labels, "labels", "", "Runner tags, comma separated")

View file

@ -404,7 +404,7 @@ func runExec(ctx context.Context, execArgs *executeArgs) func(cmd *cobra.Command
NoSkipCheckout: execArgs.noSkipCheckout,
// PresetGitHubContext: preset,
// EventJSON: string(eventJSON),
ContainerNamePrefix: fmt.Sprintf("GITEA-ACTIONS-TASK-%s", eventName),
ContainerNamePrefix: fmt.Sprintf("FORGEJO-ACTIONS-TASK-%s", eventName),
ContainerMaxLifetime: maxLifetime,
ContainerNetworkMode: container.NetworkMode(execArgs.network),
DefaultActionInstance: execArgs.defaultActionsUrl,
@ -458,7 +458,7 @@ func loadExecCmd(ctx context.Context) *cobra.Command {
execCmd.Flags().BoolVarP(&execArg.runList, "list", "l", false, "list workflows")
execCmd.Flags().StringVarP(&execArg.job, "job", "j", "", "run a specific job ID")
execCmd.Flags().StringVarP(&execArg.event, "event", "E", "", "run a event name")
execCmd.PersistentFlags().StringVarP(&execArg.workflowsPath, "workflows", "W", "./.gitea/workflows/", "path to workflow file(s)")
execCmd.PersistentFlags().StringVarP(&execArg.workflowsPath, "workflows", "W", "./.forgejo/workflows/", "path to workflow file(s)")
execCmd.PersistentFlags().StringVarP(&execArg.workdir, "directory", "C", ".", "working directory")
execCmd.PersistentFlags().BoolVarP(&execArg.noWorkflowRecurse, "no-recurse", "", false, "Flag to disable running workflows from subdirectories of specified path in '--workflows'/'-W' flag")
execCmd.Flags().BoolVarP(&execArg.autodetectEvent, "detect-event", "", false, "Use first event type from workflow as event that triggered the workflow")
@ -480,7 +480,7 @@ func loadExecCmd(ctx context.Context) *cobra.Command {
execCmd.PersistentFlags().StringVarP(&execArg.artifactServerPath, "artifact-server-path", "", ".", "Defines the path where the artifact server stores uploads and retrieves downloads from. If not specified the artifact server will not start.")
execCmd.PersistentFlags().StringVarP(&execArg.artifactServerAddr, "artifact-server-addr", "", "", "Defines the address where the artifact server listens")
execCmd.PersistentFlags().StringVarP(&execArg.artifactServerPort, "artifact-server-port", "", "34567", "Defines the port where the artifact server listens (will only bind to localhost).")
execCmd.PersistentFlags().StringVarP(&execArg.defaultActionsUrl, "default-actions-url", "", "https://github.com", "Defines the default url of action instance.")
execCmd.PersistentFlags().StringVarP(&execArg.defaultActionsUrl, "default-actions-url", "", "https://code.forgejo.org", "Defines the default url of action instance.")
execCmd.PersistentFlags().BoolVarP(&execArg.noSkipCheckout, "no-skip-checkout", "", false, "Do not skip actions/checkout")
execCmd.PersistentFlags().BoolVarP(&execArg.debug, "debug", "d", false, "enable debug log")
execCmd.PersistentFlags().BoolVarP(&execArg.dryrun, "dryrun", "n", false, "dryrun mode")

View file

@ -91,10 +91,7 @@ const (
)
var defaultLabels = []string{
"ubuntu-latest:docker://node:16-bullseye",
"ubuntu-22.04:docker://node:16-bullseye", // There's no node:16-bookworm yet
"ubuntu-20.04:docker://node:16-bullseye",
"ubuntu-18.04:docker://node:16-buster",
"docker:docker://node:16-bullseye",
}
type registerInputs struct {
@ -237,7 +234,7 @@ func printStageHelp(stage registerStage) {
case StageOverwriteLocalConfig:
log.Infoln("Runner is already registered, overwrite local config? [y/N]")
case StageInputInstance:
log.Infoln("Enter the Gitea instance URL (for example, https://gitea.com/):")
log.Infoln("Enter the Forgejo instance URL (for example, https://next.forgejo.org/):")
case StageInputToken:
log.Infoln("Enter the runner token:")
case StageInputRunnerName:
@ -315,11 +312,11 @@ func doRegister(cfg *config.Config, inputs *registerInputs) error {
}
if err != nil {
log.WithError(err).
Errorln("Cannot ping the Gitea instance server")
Errorln("Cannot ping the Forgejo instance server")
// TODO: if ping failed, retry or exit
time.Sleep(time.Second)
} else {
log.Debugln("Successfully pinged the Gitea instance server")
log.Debugln("Successfully pinged the Forgejo instance server")
break
}
}

View file

@ -48,6 +48,13 @@ func NewRunner(cfg *config.Config, reg *config.Registration, cli client.Client)
ls = append(ls, l)
}
}
if cfg.Runner.Envs == nil {
cfg.Runner.Envs = make(map[string]string, 10)
}
cfg.Runner.Envs["GITHUB_SERVER_URL"] = reg.Address
envs := make(map[string]string, len(cfg.Runner.Envs))
for k, v := range cfg.Runner.Envs {
envs[k] = v
@ -175,7 +182,7 @@ func (r *Runner) run(ctx context.Context, task *runnerv1.Task, reporter *report.
runnerConfig := &runner.Config{
// On Linux, Workdir will be like "/<parent_directory>/<owner>/<repo>"
// On Windows, Workdir will be like "\<parent_directory>\<owner>\<repo>"
Workdir: filepath.FromSlash(fmt.Sprintf("/%s/%s", r.cfg.Container.WorkdirParent, preset.Repository)),
Workdir: filepath.FromSlash(filepath.Clean(fmt.Sprintf("/%s/%s", r.cfg.Container.WorkdirParent, preset.Repository))),
BindWorkdir: false,
ActionCacheDir: filepath.FromSlash(r.cfg.Host.WorkdirParent),

View file

@ -17,14 +17,14 @@ runner:
# It will be ignored if it's empty or the file doesn't exist.
env_file: .env
# The timeout for a job to be finished.
# Please note that the Gitea instance also has a timeout (3h by default) for the job.
# So the job could be stopped by the Gitea instance if it's timeout is shorter than this.
# Please note that the Forgejo instance also has a timeout (3h by default) for the job.
# So the job could be stopped by the Forgejo instance if it's timeout is shorter than this.
timeout: 3h
# Whether skip verifying the TLS certificate of the Gitea instance.
# Whether skip verifying the TLS certificate of the Forgejo instance.
insecure: false
# The timeout for fetching the job from the Gitea instance.
# The timeout for fetching the job from the Forgejo instance.
fetch_timeout: 5s
# The interval for fetching the job from the Gitea instance.
# The interval for fetching the job from the Forgejo instance.
fetch_interval: 2s
# The labels of a runner are used to determine which jobs the runner can run, and how to run them.
# Like: ["macos-arm64:host", "ubuntu-latest:docker://node:16-bullseye", "ubuntu-22.04:docker://node:16-bullseye"]
@ -49,11 +49,11 @@ cache:
container:
# Specifies the network to which the container will connect.
# Could be host, bridge or the name of a custom network.
# If it's empty, act_runner will create a network automatically.
# If it's empty, create a network automatically.
network: ""
# Whether to use privileged mode or not when launching task containers (privileged mode is required for Docker-in-Docker).
privileged: false
# And other options to be used when the container is started (eg, --add-host=my.gitea.url:host-gateway).
# And other options to be used when the container is started (eg, --add-host=my.forgejo.url:host-gateway).
options:
# The parent directory of a job's working directory.
# If it's empty, /workspace will be used.