mirror of
https://github.com/MoreTore/openpilot.git
synced 2026-07-26 12:22:04 +08:00
buildy build
This commit is contained in:
@@ -3,237 +3,112 @@ name: Compile StarPilot
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
not_vetted:
|
||||
description: "This branch is not vetted"
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
publish_custom_branch:
|
||||
description: "Push to custom branch:"
|
||||
target_ref:
|
||||
description: "Branch to build and publish back to"
|
||||
type: string
|
||||
default: ""
|
||||
required: false
|
||||
publish_starpilot:
|
||||
description: "Push to StarPilot"
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
publish_staging:
|
||||
description: "Push to StarPilot-Staging"
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
publish_testing:
|
||||
description: "Push to StarPilot-Testing"
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
runner:
|
||||
description: "Select runner"
|
||||
type: choice
|
||||
options:
|
||||
- c3
|
||||
- c3x
|
||||
default: "c3"
|
||||
default: "master"
|
||||
required: true
|
||||
update_translations:
|
||||
description: "Update missing/outdated translations"
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
vet_existing_translations:
|
||||
description: "Vet existing translations"
|
||||
type: boolean
|
||||
default: false
|
||||
jobs:
|
||||
description: "Optional parallel job count passed to ./build"
|
||||
type: string
|
||||
default: "12"
|
||||
required: false
|
||||
|
||||
concurrency:
|
||||
group: compile-starpilot-${{ inputs.target_ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
env:
|
||||
BASE_DIR: ${{ github.workspace }}
|
||||
BUILD_DIR: "/data/openpilot"
|
||||
CUSTOM_BRANCH: ${{ inputs.publish_custom_branch }}
|
||||
GIT_EMAIL: "91348155+FrogAi@users.noreply.github.com"
|
||||
GIT_NAME: "James"
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
GIT_EMAIL: "168790843+firestar5683@users.noreply.github.com"
|
||||
GIT_NAME: "StarPilot Build Bot"
|
||||
TARGET_REF: ${{ inputs.target_ref }}
|
||||
|
||||
jobs:
|
||||
get_branch:
|
||||
runs-on: [self-hosted, "${{ inputs.runner }}"]
|
||||
outputs:
|
||||
branch: ${{ steps.get_branch.outputs.branch }}
|
||||
python_version: ${{ steps.get_python_version.outputs.python_version }}
|
||||
build_and_push:
|
||||
runs-on: [self-hosted, truenas, starpilot-build]
|
||||
timeout-minutes: 720
|
||||
steps:
|
||||
- name: Get Current Branch
|
||||
id: get_branch
|
||||
- name: Validate target branch
|
||||
shell: bash
|
||||
run: |
|
||||
cd "$BUILD_DIR"
|
||||
echo "branch=$(git rev-parse --abbrev-ref HEAD)" >> "$GITHUB_OUTPUT"
|
||||
set -euo pipefail
|
||||
|
||||
- name: Get Python Version
|
||||
id: get_python_version
|
||||
run: |
|
||||
echo "python_version=$(tr -d '[:space:]' < "$BUILD_DIR/.python-version")" >> $GITHUB_OUTPUT
|
||||
if [[ -z "${TARGET_REF}" ]]; then
|
||||
echo "target_ref is required." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
translate:
|
||||
needs: get_branch
|
||||
if: inputs.update_translations
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Configure Git Identity
|
||||
run: |
|
||||
git config --global user.name "$GIT_NAME"
|
||||
git config --global user.email "$GIT_EMAIL"
|
||||
if [[ "${TARGET_REF}" == refs/heads/* ]]; then
|
||||
echo "BUILD_BRANCH=${TARGET_REF#refs/heads/}" >> "$GITHUB_ENV"
|
||||
else
|
||||
echo "BUILD_BRANCH=${TARGET_REF}" >> "$GITHUB_ENV"
|
||||
fi
|
||||
|
||||
- name: Checkout Required Files
|
||||
- name: Checkout target branch
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ needs.get_branch.outputs.branch }}
|
||||
sparse-checkout: |
|
||||
starpilot/ui/
|
||||
selfdrive/controls/lib/alerts_offroad.json
|
||||
selfdrive/ui/
|
||||
selfdrive/ui/translations/
|
||||
selfdrive/ui/translations/auto_translate.py
|
||||
selfdrive/ui/update_translations.py
|
||||
ref: ${{ env.BUILD_BRANCH }}
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
||||
- name: Set Up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
cache: "pip"
|
||||
python-version: ${{ needs.get_branch.outputs.python_version }}
|
||||
|
||||
- name: Install Dependencies
|
||||
- name: Configure git identity
|
||||
shell: bash
|
||||
run: |
|
||||
pip install requests
|
||||
sudo apt-get update && sudo apt-get install -y --no-install-recommends qttools5-dev-tools
|
||||
set -euo pipefail
|
||||
git config user.name "$GIT_NAME"
|
||||
git config user.email "$GIT_EMAIL"
|
||||
git config http.postBuffer 104857600
|
||||
|
||||
- name: Update Translations
|
||||
- name: Ensure branch exists on origin
|
||||
shell: bash
|
||||
run: |
|
||||
python selfdrive/ui/update_translations.py --vanish
|
||||
set -euo pipefail
|
||||
git ls-remote --exit-code --heads origin "refs/heads/${BUILD_BRANCH}" >/dev/null
|
||||
|
||||
- name: Update Missing Translations
|
||||
continue-on-error: true
|
||||
timeout-minutes: 300
|
||||
- name: Link persistent sysroot
|
||||
shell: bash
|
||||
run: |
|
||||
python selfdrive/ui/translations/auto_translate.py --all-files
|
||||
set -euo pipefail
|
||||
ls -ld /runner /runner/sysroots /runner/sysroots/default || true
|
||||
ls -ld /runner/sysroots/default/usr /runner/sysroots/default/usr/local /runner/sysroots/default/usr/local/lib || true
|
||||
rm -rf .comma_sysroot
|
||||
ln -s /runner/sysroots/default .comma_sysroot
|
||||
ls -ld .comma_sysroot .comma_sysroot/usr .comma_sysroot/usr/local .comma_sysroot/usr/local/lib
|
||||
|
||||
- name: Vet Existing Translations
|
||||
if: inputs.vet_existing_translations
|
||||
continue-on-error: true
|
||||
timeout-minutes: 300
|
||||
- name: Run StarPilot device build
|
||||
shell: bash
|
||||
run: |
|
||||
python selfdrive/ui/translations/auto_translate.py --all-files --vet-translations
|
||||
set -euo pipefail
|
||||
|
||||
- name: Commit and Push Translations
|
||||
export COMMA_HOST_ROOT_DIR="/mnt/Apparition/My_App_Data/starpilot-runner/_work/${GITHUB_REPOSITORY#*/}/${GITHUB_REPOSITORY#*/}"
|
||||
export COMMA_HOST_SYSROOT_DIR="/mnt/Apparition/My_App_Data/starpilot-runner/sysroots/default"
|
||||
export COMMA_HOST_CACHE_DIR="/mnt/Apparition/My_App_Data/starpilot-runner/_work/${GITHUB_REPOSITORY#*/}/${GITHUB_REPOSITORY#*/}/.cache"
|
||||
export COMMA_SYSROOT_DIR="/runner/sysroots/default"
|
||||
|
||||
if [[ -n "${{ inputs.jobs }}" ]]; then
|
||||
./build "${{ inputs.jobs }}"
|
||||
else
|
||||
./build
|
||||
fi
|
||||
|
||||
- name: Commit build output
|
||||
shell: bash
|
||||
run: |
|
||||
if git diff --quiet selfdrive/ui/translations/*.ts; then
|
||||
echo "No translation updates detected."
|
||||
set -euo pipefail
|
||||
|
||||
if [[ -z "$(git status --porcelain --untracked-files=no)" ]]; then
|
||||
echo "No build output changes detected."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git fetch --unshallow origin "${{ needs.get_branch.outputs.branch }}"
|
||||
git checkout "${{ needs.get_branch.outputs.branch }}"
|
||||
git add selfdrive/ui/translations/*.ts
|
||||
git commit --amend --no-edit
|
||||
git push --force origin "${{ needs.get_branch.outputs.branch }}"
|
||||
git add -u
|
||||
git commit -m "build"
|
||||
|
||||
build_and_push:
|
||||
needs: [get_branch, translate]
|
||||
if: ${{ !failure() && !cancelled() && needs.get_branch.result == 'success' }}
|
||||
runs-on: [self-hosted, "${{ inputs.runner }}"]
|
||||
permissions:
|
||||
contents: write
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ${{ env.BUILD_DIR }}
|
||||
steps:
|
||||
- name: Configure Git
|
||||
- name: Push build commit
|
||||
shell: bash
|
||||
run: |
|
||||
git config http.postBuffer 104857600
|
||||
git config user.name "$GIT_NAME"
|
||||
git config user.email "$GIT_EMAIL"
|
||||
git remote set-url origin "https://${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/FrogAi/StarPilot.git"
|
||||
|
||||
- name: Sync Translation Updates
|
||||
if: inputs.update_translations
|
||||
run: |
|
||||
git fetch origin "${{ needs.get_branch.outputs.branch }}"
|
||||
git reset --hard FETCH_HEAD
|
||||
|
||||
- name: Take Ownership of Build Directory
|
||||
run: |
|
||||
sudo chown -R $(whoami):$(whoami) .
|
||||
|
||||
- name: Clean Build Artifacts
|
||||
run: |
|
||||
find . -name "matlab.*.md" -delete
|
||||
|
||||
find . -type d \( -iname "debug" -o -iname "test" -o -iname "tests" -o -name '__pycache__' \) -exec rm -rf {} +
|
||||
|
||||
find . -type f \( \
|
||||
-name '*.a' -o \
|
||||
-name '*.o' -o \
|
||||
-name '*.onnx' -o \
|
||||
-name '*.os' -o \
|
||||
-name '*.pyc' -o \
|
||||
-name 'moc_*' \
|
||||
\) -delete
|
||||
|
||||
find .github -mindepth 1 -maxdepth 1 ! -name 'workflows' -exec rm -rf {} +
|
||||
find .github/workflows -mindepth 1 ! \( \
|
||||
-type f \( \
|
||||
-name 'compile_starpilot.yaml' -o \
|
||||
-name 'review_pull_request.yaml' -o \
|
||||
-name 'schedule_update.yaml' -o \
|
||||
-name 'update_pr_branch.yaml' -o \
|
||||
-name 'update_release_branch.yaml' -o \
|
||||
-name 'update_tinygrad.yaml' \
|
||||
\) \
|
||||
\) -exec rm -rf {} +
|
||||
|
||||
find panda/board -type f \
|
||||
! -name '__init__.py' \
|
||||
! -name 'bootstub.panda.bin' \
|
||||
! -name 'bootstub.panda_h7.bin' \
|
||||
! -name 'panda.bin.signed' \
|
||||
! -name 'panda_h7.bin.signed' \
|
||||
-delete
|
||||
|
||||
find third_party/ -name '*Darwin*' -exec rm -rf {} +
|
||||
find third_party/ -name '*x86*' -exec rm -rf {} +
|
||||
|
||||
rm -f .gitignore .gitmodules .gitattributes .lfsconfig .overlay_init
|
||||
|
||||
rm -rf .sconsign.dblite .vscode/ Jenkinsfile release/ scripts/ site_scons/ teleoprtc_repo/
|
||||
|
||||
find . -type d -empty ! -path "./.git*" -delete
|
||||
|
||||
touch prebuilt
|
||||
[ "${{ inputs.not_vetted }}" = "true" ] && touch not_vetted || true
|
||||
|
||||
- name: Add Update Date File
|
||||
if: inputs.publish_staging
|
||||
continue-on-error: true
|
||||
run: |
|
||||
curl -fLsS https://raw.githubusercontent.com/FrogAi/StarPilot/StarPilot-Staging/.github/update_date -o .github/update_date || echo "No update_date found, skipping..."
|
||||
|
||||
- name: Commit and Push Build
|
||||
run: |
|
||||
git add -f .
|
||||
git commit -m "Compile StarPilot"
|
||||
git push --force origin HEAD
|
||||
|
||||
if [ "${{ inputs.publish_starpilot }}" = "true" ]; then
|
||||
git push --force origin HEAD:StarPilot
|
||||
fi
|
||||
|
||||
if [ "${{ inputs.publish_staging }}" = "true" ]; then
|
||||
git push --force origin HEAD:StarPilot-Staging
|
||||
fi
|
||||
|
||||
if [ "${{ inputs.publish_testing }}" = "true" ]; then
|
||||
git push --force origin HEAD:StarPilot-Testing
|
||||
fi
|
||||
|
||||
if [ -n "$CUSTOM_BRANCH" ]; then
|
||||
git push --force origin HEAD:"$CUSTOM_BRANCH"
|
||||
fi
|
||||
set -euo pipefail
|
||||
git push origin "HEAD:refs/heads/${BUILD_BRANCH}"
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
name: Publish TrueNAS Runner Image
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
image_tag:
|
||||
description: "Container tag to publish to GHCR"
|
||||
type: string
|
||||
default: "latest"
|
||||
required: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Log in to GHCR
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push runner image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: tools/truenas_github_runner/Dockerfile
|
||||
push: true
|
||||
tags: ghcr.io/${{ github.repository_owner }}/starpilot-truenas-runner:${{ inputs.image_tag }}
|
||||
+17
-9
@@ -153,7 +153,7 @@ lenv = {
|
||||
}
|
||||
|
||||
# Allow callers to override cache/temp dirs used by subprocesses (e.g. tinygrad model compilation).
|
||||
for key in ("HOME", "TMPDIR", "XDG_CACHE_HOME", "CACHEDB"):
|
||||
for key in ("HOME", "TMPDIR", "XDG_CACHE_HOME", "CACHEDB", "PARAMS_ROOT"):
|
||||
if key in os.environ:
|
||||
lenv[key] = os.environ[key]
|
||||
|
||||
@@ -404,12 +404,22 @@ if arch == "larch64" and os.environ.get("SP_TICI_SYSROOT"):
|
||||
qt_arm_moc = os.path.join(qt_tool_bin, "moc")
|
||||
qt_arm_uic = os.path.join(qt_tool_bin, "uic")
|
||||
qt_arm_rcc = os.path.join(qt_tool_bin, "rcc")
|
||||
qt_host_bin = os.environ.get("SP_QT_HOST_BIN", "/usr/lib/qt5/bin")
|
||||
qt_host_moc = os.environ.get("SP_QT_HOST_MOC", os.path.join(qt_host_bin, "moc"))
|
||||
qt_host_uic = os.environ.get("SP_QT_HOST_UIC", os.path.join(qt_host_bin, "uic"))
|
||||
qt_host_rcc = os.environ.get("SP_QT_HOST_RCC", "rcc")
|
||||
if platform.machine() in ("aarch64", "arm64"):
|
||||
if os.path.isfile(qt_arm_moc):
|
||||
if "SP_QT_HOST_MOC" in os.environ:
|
||||
qt_env['QT3_MOC'] = qt_host_moc
|
||||
elif os.path.isfile(qt_arm_moc):
|
||||
qt_env['QT3_MOC'] = qt_arm_moc
|
||||
if os.path.isfile(qt_arm_uic):
|
||||
if "SP_QT_HOST_UIC" in os.environ:
|
||||
qt_env['QT3_UIC'] = qt_host_uic
|
||||
elif os.path.isfile(qt_arm_uic):
|
||||
qt_env['QT3_UIC'] = qt_arm_uic
|
||||
if os.path.isfile(qt_arm_rcc):
|
||||
if "SP_QT_HOST_RCC" in os.environ:
|
||||
qt_env['SP_QT_RCC'] = qt_host_rcc
|
||||
elif os.path.isfile(qt_arm_rcc):
|
||||
qt_env['SP_QT_RCC'] = qt_arm_rcc
|
||||
else:
|
||||
qt_qemu = shutil.which("qemu-aarch64-static") or shutil.which("qemu-aarch64")
|
||||
@@ -417,19 +427,17 @@ if arch == "larch64" and os.environ.get("SP_TICI_SYSROOT"):
|
||||
if qt_qemu and os.path.isfile(qt_arm_moc):
|
||||
qt_env['QT3_MOC'] = f"{qt_qemu} -L {qt_tool_root} {qt_arm_moc}"
|
||||
else:
|
||||
qt_host_bin = os.environ.get("SP_QT_HOST_BIN", "/usr/lib/qt5/bin")
|
||||
qt_env['QT3_MOC'] = os.environ.get("SP_QT_HOST_MOC", os.path.join(qt_host_bin, "moc"))
|
||||
qt_env['QT3_MOC'] = qt_host_moc
|
||||
|
||||
if qt_qemu and os.path.isfile(qt_arm_uic):
|
||||
qt_env['QT3_UIC'] = f"{qt_qemu} -L {qt_tool_root} {qt_arm_uic}"
|
||||
else:
|
||||
qt_host_bin = os.environ.get("SP_QT_HOST_BIN", "/usr/lib/qt5/bin")
|
||||
qt_env['QT3_UIC'] = os.environ.get("SP_QT_HOST_UIC", os.path.join(qt_host_bin, "uic"))
|
||||
qt_env['QT3_UIC'] = qt_host_uic
|
||||
|
||||
if qt_qemu and os.path.isfile(qt_arm_rcc):
|
||||
qt_env['SP_QT_RCC'] = f"{qt_qemu} -L {qt_tool_root} {qt_arm_rcc}"
|
||||
else:
|
||||
qt_env['SP_QT_RCC'] = os.environ.get("SP_QT_HOST_RCC", "rcc")
|
||||
qt_env['SP_QT_RCC'] = qt_host_rcc
|
||||
|
||||
qt_env['CPPPATH'] += qt_dirs + ["#third_party/qrcode"]
|
||||
qt_flags = [
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
# TrueNAS SCALE GitHub Build Runner
|
||||
|
||||
This setup runs a single GitHub self-hosted runner as a TrueNAS SCALE custom app and routes the `Compile StarPilot` workflow onto that runner.
|
||||
|
||||
The app container:
|
||||
|
||||
- registers one repository-scoped GitHub Actions runner
|
||||
- stays visible in the TrueNAS Apps UI
|
||||
- mounts the host Docker socket so `./build` can launch the existing larch64 build container flow
|
||||
- persists runner state and build caches in one dataset mounted at `/runner`
|
||||
|
||||
## What this workflow does
|
||||
|
||||
`.github/workflows/compile_starpilot.yaml` now:
|
||||
|
||||
- lets an admin choose a `target_ref` branch from the Actions UI
|
||||
- checks out that branch on the NAS runner
|
||||
- runs `./build`
|
||||
- prunes the tree with `scripts/ci_package_prebuilt_tree.sh`
|
||||
- commits the result as `build`
|
||||
- pushes that commit back to the selected branch without force-pushing
|
||||
|
||||
Use a branch intended for built output. The prune step removes developer-facing files and is not meant for normal day-to-day development branches.
|
||||
|
||||
## 1. Publish the runner image
|
||||
|
||||
You need a registry image for TrueNAS to deploy. The repo includes `.github/workflows/publish_truenas_runner.yaml` for this.
|
||||
|
||||
1. Open **Actions** on GitHub.
|
||||
2. Run **Publish TrueNAS Runner Image**.
|
||||
3. Leave `image_tag` as `latest` unless you want a versioned tag.
|
||||
4. After it finishes, the image is available at:
|
||||
|
||||
```text
|
||||
ghcr.io/<repo-owner>/starpilot-truenas-runner:latest
|
||||
```
|
||||
|
||||
If you prefer to build it locally, run:
|
||||
|
||||
```bash
|
||||
docker build -f tools/truenas_github_runner/Dockerfile -t ghcr.io/<repo-owner>/starpilot-truenas-runner:latest .
|
||||
docker push ghcr.io/<repo-owner>/starpilot-truenas-runner:latest
|
||||
```
|
||||
|
||||
## 2. Create a runner token
|
||||
|
||||
Generate a repository-scoped self-hosted runner token in GitHub:
|
||||
|
||||
1. Open the repository.
|
||||
2. Go to **Settings > Actions > Runners**.
|
||||
3. Click **New self-hosted runner**.
|
||||
4. Choose **Linux** and **x64**.
|
||||
5. Copy the one-time registration token from the generated setup commands.
|
||||
|
||||
That token expires quickly. Paste it into TrueNAS during deployment and restart the app if you need to re-register.
|
||||
|
||||
## 3. Deploy on TrueNAS SCALE
|
||||
|
||||
TrueNAS custom apps support Docker Compose YAML through **Apps > Discover Apps > Custom App > Install via YAML**.
|
||||
|
||||
Create a dataset for persistent runner state first, for example:
|
||||
|
||||
```text
|
||||
/mnt/<pool>/apps/starpilot-runner
|
||||
```
|
||||
|
||||
Then paste this compose YAML into TrueNAS after replacing the placeholders:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
starpilot-runner:
|
||||
image: ghcr.io/<repo-owner>/starpilot-truenas-runner:latest
|
||||
container_name: starpilot-runner
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
GITHUB_REPOSITORY_URL: https://github.com/<repo-owner>/<repo-name>
|
||||
RUNNER_NAME: starpilot-truenas-runner
|
||||
RUNNER_LABELS: self-hosted,truenas,starpilot-build
|
||||
RUNNER_WORKDIR: /runner/_work
|
||||
RUNNER_TOKEN: <paste-one-time-runner-token>
|
||||
DOCKER_GID: ""
|
||||
REMOVE_RUNNER_ON_EXIT: "0"
|
||||
volumes:
|
||||
- /mnt/<pool>/apps/starpilot-runner:/runner
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
```
|
||||
|
||||
If the container starts but cannot talk to Docker, inspect the Docker socket group on TrueNAS and set `DOCKER_GID` to that numeric group id.
|
||||
|
||||
## 4. Verify runner registration
|
||||
|
||||
Confirm all of the following:
|
||||
|
||||
- the app shows as `Running` in TrueNAS
|
||||
- the container passes its healthcheck
|
||||
- GitHub shows the runner as online with labels `self-hosted`, `truenas`, and `starpilot-build`
|
||||
|
||||
## 5. Run a build
|
||||
|
||||
1. Open **Actions > Compile StarPilot**.
|
||||
2. Click **Run workflow**.
|
||||
3. Enter the branch name in `target_ref`.
|
||||
4. Optionally set `jobs` to the parallelism you want for `./build`.
|
||||
5. Start the run.
|
||||
|
||||
On success, the workflow pushes a new commit named `build` back to that branch.
|
||||
|
||||
## Operational notes
|
||||
|
||||
- `RUNNER_TOKEN` is only required on first registration or when you want to replace a stale runner with the same name.
|
||||
- Runner state is persisted in `/runner`, so normal restarts do not need a new token.
|
||||
- `REMOVE_RUNNER_ON_EXIT=1` enables best-effort deregistration on shutdown, but that only works when the provided token is still valid.
|
||||
- The build cache, GitHub workspace, and `.comma_sysroot` data all persist under the runner dataset as long as the workflow runs in the same mounted work area.
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "${ROOT_DIR}"
|
||||
|
||||
find . -name "matlab.*.md" -delete
|
||||
|
||||
find . -type d \( -iname "debug" -o -iname "test" -o -iname "tests" -o -name "__pycache__" \) -exec rm -rf {} +
|
||||
|
||||
find . -type f \( \
|
||||
-name "*.a" -o \
|
||||
-name "*.o" -o \
|
||||
-name "*.onnx" -o \
|
||||
-name "*.os" -o \
|
||||
-name "*.pyc" -o \
|
||||
-name "moc_*" \
|
||||
\) -delete
|
||||
|
||||
find .github -mindepth 1 -maxdepth 1 ! -name "workflows" -exec rm -rf {} +
|
||||
find .github/workflows -mindepth 1 ! \( \
|
||||
-type f \( \
|
||||
-name "compile_starpilot.yaml" -o \
|
||||
-name "publish_truenas_runner.yaml" -o \
|
||||
-name "review_pull_request.yaml" -o \
|
||||
-name "schedule_update.yaml" -o \
|
||||
-name "update_pr_branch.yaml" -o \
|
||||
-name "update_release_branch.yaml" -o \
|
||||
-name "update_tinygrad.yaml" \
|
||||
\) \
|
||||
\) -exec rm -rf {} +
|
||||
|
||||
find panda/board -type f \
|
||||
! -name "__init__.py" \
|
||||
! -name "bootstub.panda.bin" \
|
||||
! -name "bootstub.panda_h7.bin" \
|
||||
! -name "panda.bin.signed" \
|
||||
! -name "panda_h7.bin.signed" \
|
||||
-delete
|
||||
|
||||
find third_party/ -name "*Darwin*" -exec rm -rf {} +
|
||||
find third_party/ -name "*x86*" -exec rm -rf {} +
|
||||
|
||||
rm -f .gitignore .gitmodules .gitattributes .lfsconfig .overlay_init
|
||||
|
||||
rm -rf .sconsign.dblite .vscode/ Jenkinsfile release/ scripts/ site_scons/ teleoprtc_repo/
|
||||
|
||||
find . -type d -empty ! -path "./.git*" -delete
|
||||
|
||||
touch prebuilt
|
||||
@@ -5,6 +5,9 @@ set -euo pipefail
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "${ROOT_DIR}"
|
||||
|
||||
HOST_ROOT_DIR="${COMMA_HOST_ROOT_DIR:-${ROOT_DIR}}"
|
||||
DOCKER_RUN_USER="${COMMA_DOCKER_RUN_USER:-$(id -u):$(id -g)}"
|
||||
|
||||
# Make Docker Desktop binaries discoverable (docker + credential helpers) even
|
||||
# when the caller shell PATH is minimal.
|
||||
if [[ -d /Applications/Docker.app/Contents/Resources/bin ]]; then
|
||||
@@ -14,6 +17,9 @@ fi
|
||||
IMAGE_NAME="${COMMA_BUILD_IMAGE:-starpilot-larch64-builder:latest}"
|
||||
SYSROOT_DIR_DEFAULT="${ROOT_DIR}/.comma_sysroot"
|
||||
SYSROOT_DIR="${COMMA_SYSROOT_DIR:-${SYSROOT_DIR_DEFAULT}}"
|
||||
HOST_SYSROOT_DIR="${COMMA_HOST_SYSROOT_DIR:-${SYSROOT_DIR}}"
|
||||
HOST_CACHE_DIR="${COMMA_HOST_CACHE_DIR:-${HOST_ROOT_DIR}/.cache}"
|
||||
HOST_DOCKERFILE_PATH="${COMMA_HOST_DOCKERFILE_PATH:-${HOST_ROOT_DIR}/tools/laptop_device_build/Dockerfile}"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
@@ -98,11 +104,23 @@ detect_engine() {
|
||||
err "No container runtime found (install docker or podman)."
|
||||
}
|
||||
|
||||
build_container_image_cmd() {
|
||||
local engine="$1"
|
||||
shift
|
||||
|
||||
if [[ "${engine##*/}" == "docker" ]] && "${engine}" buildx version >/dev/null 2>&1; then
|
||||
"${engine}" buildx build --load --platform linux/arm64 "$@"
|
||||
return
|
||||
fi
|
||||
|
||||
"${engine}" build --pull --platform linux/arm64 "$@"
|
||||
}
|
||||
|
||||
ensure_image_exists() {
|
||||
local engine="$1"
|
||||
if ! "${engine}" image inspect "${IMAGE_NAME}" >/dev/null 2>&1; then
|
||||
echo "Container image ${IMAGE_NAME} not found. Building it now..."
|
||||
"${engine}" build --pull --platform linux/arm64 -f tools/laptop_device_build/Dockerfile -t "${IMAGE_NAME}" .
|
||||
build_container_image_cmd "${engine}" --pull -f "${HOST_DOCKERFILE_PATH}" -t "${IMAGE_NAME}" "${HOST_ROOT_DIR}"
|
||||
fi
|
||||
assert_image_arch "${engine}"
|
||||
ensure_image_capnp_version "${engine}"
|
||||
@@ -161,7 +179,7 @@ ensure_image_capnp_version() {
|
||||
fi
|
||||
|
||||
echo "Container image ${IMAGE_NAME} has Cap'n Proto ${actual:-unknown}, expected ${expected}. Rebuilding it now..."
|
||||
"${engine}" build --pull --platform linux/arm64 -f tools/laptop_device_build/Dockerfile -t "${IMAGE_NAME}" .
|
||||
build_container_image_cmd "${engine}" --pull -f "${HOST_DOCKERFILE_PATH}" -t "${IMAGE_NAME}" "${HOST_ROOT_DIR}"
|
||||
|
||||
actual="$(image_capnp_version "${engine}")"
|
||||
if [[ "${actual}" != "${expected}" ]]; then
|
||||
@@ -191,9 +209,9 @@ default_jobs() {
|
||||
build_container_image() {
|
||||
local engine
|
||||
engine="$(detect_engine)"
|
||||
"${engine}" build --pull --platform linux/arm64 \
|
||||
-f tools/laptop_device_build/Dockerfile \
|
||||
-t "${IMAGE_NAME}" .
|
||||
build_container_image_cmd "${engine}" --pull \
|
||||
-f "${HOST_DOCKERFILE_PATH}" \
|
||||
-t "${IMAGE_NAME}" "${HOST_ROOT_DIR}"
|
||||
assert_image_arch "${engine}"
|
||||
}
|
||||
|
||||
@@ -351,12 +369,13 @@ setup_sysroot_from_agnos() {
|
||||
local engine
|
||||
engine="$(detect_engine)"
|
||||
ensure_image_exists "${engine}"
|
||||
mkdir -p "${SYSROOT_DIR}" "${ROOT_DIR}/.cache/agnos"
|
||||
mkdir -p "${SYSROOT_DIR}" "${ROOT_DIR}/.cache/agnos" "${HOST_CACHE_DIR}/agnos"
|
||||
|
||||
"${engine}" run --rm --platform linux/arm64 \
|
||||
-v "${ROOT_DIR}:/work" \
|
||||
-v "${SYSROOT_DIR}:/opt/tici-sysroot" \
|
||||
-v "${ROOT_DIR}/.cache:/work/.cache" \
|
||||
--user "${DOCKER_RUN_USER}" \
|
||||
-v "${HOST_ROOT_DIR}:/work" \
|
||||
-v "${HOST_SYSROOT_DIR}:/opt/tici-sysroot" \
|
||||
-v "${HOST_CACHE_DIR}:/work/.cache" \
|
||||
-w /work \
|
||||
"${IMAGE_NAME}" \
|
||||
python3 tools/laptop_device_build/extract_sysroot_from_agnos.py \
|
||||
@@ -380,7 +399,7 @@ run_larch64_scons() {
|
||||
echo " jobs: ${jobs}"
|
||||
echo " note: warp artifact precompile can take several minutes on first run"
|
||||
|
||||
mkdir -p "${ROOT_DIR}/.cache/scons"
|
||||
mkdir -p "${ROOT_DIR}/.cache/scons" "${HOST_CACHE_DIR}/scons"
|
||||
|
||||
local extra_args=""
|
||||
local jobs_prefix="-j${jobs}"
|
||||
@@ -407,7 +426,10 @@ export SP_BUILD_WARP_ARTIFACTS="\${SP_BUILD_WARP_ARTIFACTS:-0}"
|
||||
export SP_SKIP_DM_TINYGRAD_PKL="\${SP_SKIP_DM_TINYGRAD_PKL:-1}"
|
||||
export LD_LIBRARY_PATH=/usr/local/lib:/usr/lib/aarch64-linux-gnu:/lib/aarch64-linux-gnu:/opt/tici-sysroot/usr/local/lib:/opt/tici-sysroot/usr/lib/aarch64-linux-gnu:/opt/tici-sysroot/lib/aarch64-linux-gnu:/system/vendor/lib64:\${LD_LIBRARY_PATH:-}
|
||||
export TMPDIR=/tmp
|
||||
export HOME=/tmp
|
||||
export PARAMS_ROOT=/tmp/params
|
||||
mkdir -p "\${UV_CACHE_DIR}"
|
||||
mkdir -p "\${PARAMS_ROOT}"
|
||||
UV_PROJECT_ENVIRONMENT=/work/.venv-linux-arm64 uv sync --frozen --all-extras
|
||||
source /work/.venv-linux-arm64/bin/activate
|
||||
CACHE_FLAG="--cache-disable"
|
||||
@@ -419,11 +441,12 @@ EOF
|
||||
)"
|
||||
|
||||
"${engine}" run --rm --platform linux/arm64 \
|
||||
-v "${ROOT_DIR}:/work" \
|
||||
-v "${SYSROOT_DIR}:/opt/tici-sysroot:ro" \
|
||||
-v "${SYSROOT_DIR}/system/vendor/lib64:/system/vendor/lib64:ro" \
|
||||
-v "${ROOT_DIR}/.cache:/work/.cache" \
|
||||
-v "${ROOT_DIR}/.cache/scons:/data/scons_cache" \
|
||||
--user "${DOCKER_RUN_USER}" \
|
||||
-v "${HOST_ROOT_DIR}:/work" \
|
||||
-v "${HOST_SYSROOT_DIR}:/opt/tici-sysroot:ro" \
|
||||
-v "${HOST_SYSROOT_DIR}/system/vendor/lib64:/system/vendor/lib64:ro" \
|
||||
-v "${HOST_CACHE_DIR}:/work/.cache" \
|
||||
-v "${HOST_CACHE_DIR}/scons:/data/scons_cache" \
|
||||
-w /work \
|
||||
"${IMAGE_NAME}" bash -lc "${cmd}"
|
||||
|
||||
@@ -537,7 +560,7 @@ run_manager() {
|
||||
ensure_image_exists "${engine}"
|
||||
assert_runtime_machine "${engine}"
|
||||
ensure_sysroot_layout
|
||||
mkdir -p "${ROOT_DIR}/.cache/scons"
|
||||
mkdir -p "${ROOT_DIR}/.cache/scons" "${HOST_CACHE_DIR}/scons"
|
||||
|
||||
local manager_args_q=""
|
||||
if [[ "${#manager_args[@]}" -gt 0 ]]; then
|
||||
@@ -556,7 +579,10 @@ export SP_TICI_SYSROOT=/opt/tici-sysroot
|
||||
export SP_BUILD_WARP_ARTIFACTS="\${SP_BUILD_WARP_ARTIFACTS:-0}"
|
||||
export LD_LIBRARY_PATH=/usr/local/lib:/usr/lib/aarch64-linux-gnu:/lib/aarch64-linux-gnu:/opt/tici-sysroot/usr/local/lib:/opt/tici-sysroot/usr/lib/aarch64-linux-gnu:/opt/tici-sysroot/lib/aarch64-linux-gnu:/system/vendor/lib64:\${LD_LIBRARY_PATH:-}
|
||||
export TMPDIR=/tmp
|
||||
export HOME=/tmp
|
||||
export PARAMS_ROOT=/tmp/params
|
||||
mkdir -p "\${UV_CACHE_DIR}"
|
||||
mkdir -p "\${PARAMS_ROOT}"
|
||||
UV_PROJECT_ENVIRONMENT=/work/.venv-linux-arm64 uv sync --frozen --all-extras
|
||||
source /work/.venv-linux-arm64/bin/activate
|
||||
cd /work
|
||||
@@ -565,11 +591,12 @@ EOF
|
||||
)"
|
||||
|
||||
"${engine}" run --rm --platform linux/arm64 \
|
||||
-v "${ROOT_DIR}:/work" \
|
||||
-v "${SYSROOT_DIR}:/opt/tici-sysroot:ro" \
|
||||
-v "${SYSROOT_DIR}/system/vendor/lib64:/system/vendor/lib64:ro" \
|
||||
-v "${ROOT_DIR}/.cache:/work/.cache" \
|
||||
-v "${ROOT_DIR}/.cache/scons:/data/scons_cache" \
|
||||
--user "${DOCKER_RUN_USER}" \
|
||||
-v "${HOST_ROOT_DIR}:/work" \
|
||||
-v "${HOST_SYSROOT_DIR}:/opt/tici-sysroot:ro" \
|
||||
-v "${HOST_SYSROOT_DIR}/system/vendor/lib64:/system/vendor/lib64:ro" \
|
||||
-v "${HOST_CACHE_DIR}:/work/.cache" \
|
||||
-v "${HOST_CACHE_DIR}/scons:/data/scons_cache" \
|
||||
-w /work \
|
||||
"${IMAGE_NAME}" bash -lc "${cmd}"
|
||||
}
|
||||
@@ -580,11 +607,12 @@ run_shell() {
|
||||
ensure_image_exists "${engine}"
|
||||
ensure_sysroot_layout
|
||||
"${engine}" run --rm -it --platform linux/arm64 \
|
||||
-v "${ROOT_DIR}:/work" \
|
||||
-v "${SYSROOT_DIR}:/opt/tici-sysroot:ro" \
|
||||
-v "${SYSROOT_DIR}/system/vendor/lib64:/system/vendor/lib64:ro" \
|
||||
-v "${ROOT_DIR}/.cache:/work/.cache" \
|
||||
-v "${ROOT_DIR}/.cache/scons:/data/scons_cache" \
|
||||
--user "${DOCKER_RUN_USER}" \
|
||||
-v "${HOST_ROOT_DIR}:/work" \
|
||||
-v "${HOST_SYSROOT_DIR}:/opt/tici-sysroot:ro" \
|
||||
-v "${HOST_SYSROOT_DIR}/system/vendor/lib64:/system/vendor/lib64:ro" \
|
||||
-v "${HOST_CACHE_DIR}:/work/.cache" \
|
||||
-v "${HOST_CACHE_DIR}/scons:/data/scons_cache" \
|
||||
-w /work \
|
||||
"${IMAGE_NAME}" bash
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import json
|
||||
import os
|
||||
Import('env', 'qt_env', 'arch', 'common', 'messaging', 'visionipc', 'transformations')
|
||||
|
||||
base_libs = [common, messaging, visionipc, transformations,
|
||||
@@ -65,7 +66,7 @@ with open(File("translations/languages.json").abspath) as f:
|
||||
languages = json.loads(f.read())
|
||||
translation_sources = [f"#selfdrive/ui/translations/{l}.ts" for l in languages.values()]
|
||||
translation_targets = [src.replace(".ts", ".qm") for src in translation_sources]
|
||||
lrelease_bin = 'third_party/qt5/larch64/bin/lrelease' if arch == 'larch64' else 'lrelease'
|
||||
lrelease_bin = os.environ.get("SP_QT_HOST_LRELEASE", "lrelease") if arch == 'larch64' else 'lrelease'
|
||||
|
||||
lrelease = qt_env.Command(translation_targets, translation_sources, f"{lrelease_bin} $SOURCES")
|
||||
qt_env.NoClean(translation_sources)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
RUNNER_IMAGE=ghcr.io/REPLACE_ME/starpilot-truenas-runner:latest
|
||||
GITHUB_REPOSITORY_URL=https://github.com/REPLACE_ME/REPLACE_ME
|
||||
RUNNER_NAME=starpilot-truenas-runner
|
||||
RUNNER_LABELS=self-hosted,truenas,starpilot-build
|
||||
RUNNER_WORKDIR=/runner/_work
|
||||
RUNNER_TOKEN=REPLACE_WITH_ONE_TIME_GITHUB_RUNNER_TOKEN
|
||||
RUNNER_DATA_PATH=/mnt/tank/apps/starpilot-runner
|
||||
DOCKER_GID=
|
||||
REMOVE_RUNNER_ON_EXIT=0
|
||||
@@ -0,0 +1,41 @@
|
||||
FROM ubuntu:24.04
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG RUNNER_VERSION=2.334.0
|
||||
|
||||
ENV RUNNER_HOME=/runner
|
||||
ENV RUNNER_WORKDIR=/runner/_work
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
curl \
|
||||
docker.io \
|
||||
git \
|
||||
gosu \
|
||||
jq \
|
||||
sudo \
|
||||
tar \
|
||||
unzip \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN useradd --create-home --home-dir /home/runner --shell /bin/bash runner \
|
||||
&& usermod -aG sudo runner \
|
||||
&& echo "runner ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/runner
|
||||
|
||||
WORKDIR /opt/actions-runner
|
||||
|
||||
RUN curl -fsSL -o actions-runner.tar.gz \
|
||||
"https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz" \
|
||||
&& tar -xzf actions-runner.tar.gz \
|
||||
&& rm actions-runner.tar.gz \
|
||||
&& ./bin/installdependencies.sh \
|
||||
&& chown -R runner:runner /opt/actions-runner
|
||||
|
||||
COPY tools/truenas_github_runner/entrypoint.sh /usr/local/bin/truenas-runner-entrypoint
|
||||
COPY tools/truenas_github_runner/healthcheck.sh /usr/local/bin/truenas-runner-healthcheck
|
||||
|
||||
RUN chmod 755 /usr/local/bin/truenas-runner-entrypoint /usr/local/bin/truenas-runner-healthcheck
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=5 CMD ["/usr/local/bin/truenas-runner-healthcheck"]
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/truenas-runner-entrypoint"]
|
||||
@@ -0,0 +1,16 @@
|
||||
services:
|
||||
starpilot-runner:
|
||||
image: ${RUNNER_IMAGE}
|
||||
container_name: starpilot-runner
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
GITHUB_REPOSITORY_URL: ${GITHUB_REPOSITORY_URL}
|
||||
RUNNER_NAME: ${RUNNER_NAME}
|
||||
RUNNER_LABELS: ${RUNNER_LABELS}
|
||||
RUNNER_WORKDIR: ${RUNNER_WORKDIR}
|
||||
RUNNER_TOKEN: ${RUNNER_TOKEN}
|
||||
DOCKER_GID: ${DOCKER_GID:-}
|
||||
REMOVE_RUNNER_ON_EXIT: ${REMOVE_RUNNER_ON_EXIT:-0}
|
||||
volumes:
|
||||
- ${RUNNER_DATA_PATH}:/runner
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
Executable
+121
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RUNNER_HOME="${RUNNER_HOME:-/runner}"
|
||||
RUNNER_WORKDIR="${RUNNER_WORKDIR:-${RUNNER_HOME}/_work}"
|
||||
RUNNER_LABELS="${RUNNER_LABELS:-self-hosted,truenas,starpilot-build}"
|
||||
RUNNER_NAME="${RUNNER_NAME:-$(hostname)}"
|
||||
REMOVE_RUNNER_ON_EXIT="${REMOVE_RUNNER_ON_EXIT:-0}"
|
||||
RUNNER_ALLOW_RUNASROOT=1
|
||||
|
||||
export RUNNER_ALLOW_RUNASROOT
|
||||
|
||||
log() {
|
||||
printf '[truenas-runner] %s\n' "$*"
|
||||
}
|
||||
|
||||
fail() {
|
||||
printf '[truenas-runner] ERROR: %s\n' "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
require_env() {
|
||||
local name="$1"
|
||||
[[ -n "${!name:-}" ]] || fail "Missing required environment variable: ${name}"
|
||||
}
|
||||
|
||||
ensure_docker_access() {
|
||||
if [[ ! -S /var/run/docker.sock ]]; then
|
||||
fail "Docker socket /var/run/docker.sock is not mounted."
|
||||
fi
|
||||
|
||||
if [[ -n "${DOCKER_GID:-}" ]]; then
|
||||
if ! getent group docker-host >/dev/null 2>&1; then
|
||||
groupadd --gid "${DOCKER_GID}" docker-host
|
||||
fi
|
||||
usermod -aG docker-host runner
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_dirs() {
|
||||
mkdir -p "${RUNNER_HOME}" "${RUNNER_WORKDIR}" "${RUNNER_HOME}/.state" "${RUNNER_HOME}/.config"
|
||||
|
||||
chown -R runner:runner "${RUNNER_HOME}"
|
||||
}
|
||||
|
||||
restore_runner_config() {
|
||||
local file=""
|
||||
for file in .runner .credentials .credentials_rsaparams; do
|
||||
if [[ -f "${RUNNER_HOME}/.config/${file}" ]]; then
|
||||
cp -f "${RUNNER_HOME}/.config/${file}" "/opt/actions-runner/${file}"
|
||||
chown runner:runner "/opt/actions-runner/${file}"
|
||||
else
|
||||
rm -f "/opt/actions-runner/${file}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
persist_runner_config() {
|
||||
local file=""
|
||||
for file in .runner .credentials .credentials_rsaparams; do
|
||||
if [[ -f "/opt/actions-runner/${file}" ]]; then
|
||||
cp -f "/opt/actions-runner/${file}" "${RUNNER_HOME}/.config/${file}"
|
||||
chown runner:runner "${RUNNER_HOME}/.config/${file}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
configure_runner() {
|
||||
require_env GITHUB_REPOSITORY_URL
|
||||
|
||||
if [[ -f /opt/actions-runner/.runner ]]; then
|
||||
log "Existing runner configuration detected; skipping registration."
|
||||
return
|
||||
fi
|
||||
|
||||
require_env RUNNER_TOKEN
|
||||
|
||||
log "Registering GitHub runner ${RUNNER_NAME} for ${GITHUB_REPOSITORY_URL}"
|
||||
|
||||
gosu runner /opt/actions-runner/config.sh \
|
||||
--url "${GITHUB_REPOSITORY_URL}" \
|
||||
--token "${RUNNER_TOKEN}" \
|
||||
--name "${RUNNER_NAME}" \
|
||||
--labels "${RUNNER_LABELS}" \
|
||||
--work "${RUNNER_WORKDIR}" \
|
||||
--unattended \
|
||||
--replace
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
local exit_code=$?
|
||||
|
||||
if [[ -n "${runner_pid:-}" ]]; then
|
||||
kill "${runner_pid}" >/dev/null 2>&1 || true
|
||||
wait "${runner_pid}" || true
|
||||
fi
|
||||
|
||||
if [[ "${REMOVE_RUNNER_ON_EXIT}" == "1" && -n "${RUNNER_TOKEN:-}" && -f /opt/actions-runner/.runner ]]; then
|
||||
log "Removing runner registration on exit."
|
||||
gosu runner /opt/actions-runner/config.sh remove --token "${RUNNER_TOKEN}" || true
|
||||
fi
|
||||
|
||||
exit "${exit_code}"
|
||||
}
|
||||
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
ensure_docker_access
|
||||
prepare_dirs
|
||||
restore_runner_config
|
||||
configure_runner
|
||||
persist_runner_config
|
||||
|
||||
touch "${RUNNER_HOME}/.state/configured"
|
||||
chown runner:runner "${RUNNER_HOME}/.state/configured"
|
||||
|
||||
log "Starting runner ${RUNNER_NAME}"
|
||||
gosu runner /opt/actions-runner/run.sh &
|
||||
runner_pid=$!
|
||||
wait "${runner_pid}"
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RUNNER_HOME="${RUNNER_HOME:-/runner}"
|
||||
|
||||
test -f /opt/actions-runner/.runner
|
||||
test -f "${RUNNER_HOME}/.state/configured"
|
||||
pgrep -f "Runner.Listener" >/dev/null
|
||||
Reference in New Issue
Block a user