@@ -0,0 +1,79 @@
|
|||||||
|
# Self-hosted Renovate, run by Woodpecker on a schedule.
|
||||||
|
#
|
||||||
|
# Woodpecker has no native Renovate support, so we run the official
|
||||||
|
# renovate/renovate image as a one-shot job. The repo-level rules live in
|
||||||
|
# ./renovate.json; the GLOBAL/self-hosted settings (which platform, which repo,
|
||||||
|
# the API token) are provided here via environment so renovate.json stays a
|
||||||
|
# clean, portable repository config.
|
||||||
|
#
|
||||||
|
# SETUP (one-time):
|
||||||
|
# 1. In Gitea, create a bot user (e.g. "renovate") with write access to this
|
||||||
|
# repo, and generate a personal access token with at least:
|
||||||
|
# repo (read/write), issue (read/write), pull-request (read/write)
|
||||||
|
# 2. In Woodpecker repo settings -> Secrets, add a secret:
|
||||||
|
# name: renovate_token
|
||||||
|
# value: <the Gitea PAT>
|
||||||
|
# Make sure it is available to the "cron" event.
|
||||||
|
# 3. In Woodpecker repo settings -> Crons, add a cron:
|
||||||
|
# name: renovate
|
||||||
|
# branch: main # branch whose pipeline config is used
|
||||||
|
# schedule: "@daily" # or e.g. "0 6 * * 1" (Mondays 06:00)
|
||||||
|
#
|
||||||
|
# The step below only runs for the "cron" event named "renovate", so normal
|
||||||
|
# pushes/PRs never trigger Renovate.
|
||||||
|
|
||||||
|
when:
|
||||||
|
- event: cron
|
||||||
|
cron: renovate
|
||||||
|
|
||||||
|
skip_clone: true
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Get renovate token from OpenBao
|
||||||
|
image: quay.io/openbao/openbao:2.5.4
|
||||||
|
environment:
|
||||||
|
VAULT_ADDR: https://openbao.lumpiasty.xyz:8200
|
||||||
|
ROLE_ID:
|
||||||
|
from_secret: renovate_role_id
|
||||||
|
SECRET_ID:
|
||||||
|
from_secret: renovate_secret_id
|
||||||
|
commands:
|
||||||
|
- bao write -field token auth/approle/login
|
||||||
|
role_id=$ROLE_ID
|
||||||
|
secret_id=$SECRET_ID > /woodpecker/.vault_id
|
||||||
|
- export VAULT_TOKEN=$(cat /woodpecker/.vault_id)
|
||||||
|
- bao kv get -mount secret -field RENOVATE_TOKEN renovate > /woodpecker/renovate_token
|
||||||
|
- bao kv get -mount secret -field GITHUB_COM_TOKEN renovate > /woodpecker/github_com_token
|
||||||
|
- name: renovate
|
||||||
|
# Renovate's built-in "woodpecker" manager tracks this image automatically.
|
||||||
|
image: renovate/renovate:43.194.0
|
||||||
|
environment:
|
||||||
|
# --- platform / target ---
|
||||||
|
RENOVATE_PLATFORM: gitea
|
||||||
|
# Gitea API endpoint. Override to match your instance.
|
||||||
|
RENOVATE_ENDPOINT: https://gitea.lumpiasty.xyz/api/v1
|
||||||
|
# Only operate on this repository.
|
||||||
|
RENOVATE_AUTODISCOVER: "false"
|
||||||
|
RENOVATE_REPOSITORIES: ${CI_REPO}
|
||||||
|
# Use the committed renovate.json; don't open an onboarding PR.
|
||||||
|
RENOVATE_ONBOARDING: "false"
|
||||||
|
RENOVATE_REQUIRE_CONFIG: "optional"
|
||||||
|
# Git identity for the branches/commits Renovate creates.
|
||||||
|
RENOVATE_GIT_AUTHOR: "Renovate Bot <renovate@localhost>"
|
||||||
|
# GitHub token (read-only, no repo access) lets Renovate fetch release
|
||||||
|
# notes / changelogs and avoids GitHub API rate limits for the
|
||||||
|
# github-releases datasource (tailscale). Optional but recommended.
|
||||||
|
LOG_LEVEL: info
|
||||||
|
# Load tokens from OpenBao (written to /woodpecker by the first step) and
|
||||||
|
# run renovate.
|
||||||
|
commands:
|
||||||
|
- export RENOVATE_TOKEN=$(cat /woodpecker/renovate_token)
|
||||||
|
- export GITHUB_COM_TOKEN=$(cat /woodpecker/github_com_token)
|
||||||
|
- /usr/local/sbin/renovate-entrypoint.sh renovate
|
||||||
|
- name: Invalidate OpenBao token
|
||||||
|
image: quay.io/openbao/openbao:2.5.4
|
||||||
|
environment:
|
||||||
|
VAULT_ADDR: https://openbao.lumpiasty.xyz:8200
|
||||||
|
commands:
|
||||||
|
- export VAULT_TOKEN=$(cat /woodpecker/.vault_id)
|
||||||
|
- bao write -f auth/token/revoke-self
|
||||||
+4
-2
@@ -19,8 +19,9 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Stage 1: Build Tailscale combined binary (cross-compiled, runs natively)
|
# Stage 1: Build Tailscale combined binary (cross-compiled, runs natively)
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
FROM --platform=$BUILDPLATFORM golang:1.26-alpine AS builder
|
FROM --platform=$BUILDPLATFORM golang:1.26-alpine@sha256:91eda9776261207ea25fd06b5b7fed8d397dd2c0a283e77f2ab6e91bfa71079d AS builder
|
||||||
|
|
||||||
|
# renovate: datasource=github-releases depName=tailscale packageName=tailscale/tailscale
|
||||||
ARG TAILSCALE_VERSION=v1.98.3
|
ARG TAILSCALE_VERSION=v1.98.3
|
||||||
|
|
||||||
# Provided automatically by buildx for the target platform.
|
# Provided automatically by buildx for the target platform.
|
||||||
@@ -137,8 +138,9 @@ RUN upx --lzma --best /out/tailscale.combined
|
|||||||
# This stage runs on the TARGET platform (no --platform override): gcc then
|
# This stage runs on the TARGET platform (no --platform override): gcc then
|
||||||
# produces native target-arch binaries directly. Under buildx this is
|
# produces native target-arch binaries directly. Under buildx this is
|
||||||
# transparently emulated via binfmt/QEMU for non-native targets.
|
# transparently emulated via binfmt/QEMU for non-native targets.
|
||||||
FROM alpine:3.21 AS busybox
|
FROM alpine:3.21@sha256:48b0309ca019d89d40f670aa1bc06e426dc0931948452e8491e3d65087abc07d AS busybox
|
||||||
|
|
||||||
|
# renovate: datasource=docker depName=busybox versioning=docker
|
||||||
ARG BUSYBOX_VERSION=1.37.0
|
ARG BUSYBOX_VERSION=1.37.0
|
||||||
|
|
||||||
RUN apk add --no-cache build-base linux-headers wget bzip2 perl upx
|
RUN apk add --no-cache build-base linux-headers wget bzip2 perl upx
|
||||||
|
|||||||
@@ -265,21 +265,67 @@ Several measures are in place to avoid wearing out internal flash:
|
|||||||
|
|
||||||
## Upgrading
|
## Upgrading
|
||||||
|
|
||||||
Update the `TAILSCALE_VERSION` build arg and rebuild the image. The feature
|
Version bumps (Tailscale, busybox, base image digests) are normally proposed
|
||||||
allowlist in the Dockerfile carries forward automatically — any new
|
automatically via Renovate — see
|
||||||
`ts_omit_*` tags introduced in the new version will be omitted by default.
|
[Dependency pinning & automated updates](#dependency-pinning--automated-updates).
|
||||||
|
Merge the Renovate PR, then rebuild and redeploy.
|
||||||
|
|
||||||
|
The feature allowlist in the Dockerfile carries forward automatically across
|
||||||
|
Tailscale versions — any new `ts_omit_*` tags introduced in a new release will
|
||||||
|
be omitted by default.
|
||||||
|
|
||||||
|
To bump manually, edit `ARG TAILSCALE_VERSION` in the `Dockerfile` (so the pin
|
||||||
|
stays in version control) and rebuild:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
TAG=v1.99.0 ./build.sh --tar # rebuild all arches with the new version
|
./build.sh --tar # rebuild all arches at the pinned version
|
||||||
# or, single arch:
|
# or, override at build time without editing the Dockerfile:
|
||||||
docker buildx build --platform linux/arm64 \
|
docker buildx build --platform linux/arm64 \
|
||||||
--build-arg TAILSCALE_VERSION=v1.99.0 \
|
--build-arg TAILSCALE_VERSION=v1.100.0 \
|
||||||
--load -t mikrotik-tailscale:v1.99.0-arm64 .
|
--load -t mikrotik-tailscale:arm64 .
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dependency pinning & automated updates
|
||||||
|
|
||||||
|
All upstream dependencies are version-pinned for reproducible builds:
|
||||||
|
|
||||||
|
| Dependency | Where | Pinned form |
|
||||||
|
|---|---|---|
|
||||||
|
| Go toolchain | `Dockerfile` `FROM golang:…` | tag + `@sha256` digest |
|
||||||
|
| Alpine (busybox build base) | `Dockerfile` `FROM alpine:…` | tag + `@sha256` digest |
|
||||||
|
| Tailscale | `Dockerfile` `ARG TAILSCALE_VERSION` | git release tag |
|
||||||
|
| busybox | `Dockerfile` `ARG BUSYBOX_VERSION` | release version |
|
||||||
|
| Renovate runner | `.woodpecker/renovate.yaml` `image:` | tag |
|
||||||
|
|
||||||
|
Updates are proposed automatically by [Renovate](https://docs.renovatebot.com/),
|
||||||
|
run **self-hosted** from a Woodpecker cron pipeline (Woodpecker has no native
|
||||||
|
Renovate support):
|
||||||
|
|
||||||
|
- `renovate.json` — repository rules. All dependencies follow the latest
|
||||||
|
upstream releases (including major versions); each bump arrives as its own PR
|
||||||
|
that the multi-arch build validates before you merge. Base image tags also
|
||||||
|
get their `@sha256` digests refreshed via `pinDigests`. The one special rule:
|
||||||
|
- `tailscale` only follows **stable** releases — Tailscale uses even minor
|
||||||
|
versions for stable (`v1.98.x`) and odd for unstable (`v1.99.x`), so the
|
||||||
|
rule filters to even minors.
|
||||||
|
- `.woodpecker/renovate.yaml` — the scheduled job that runs `renovate/renovate`
|
||||||
|
against this repo.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Renovate repo config
|
||||||
|
docker run --rm -e RENOVATE_CONFIG_TYPE=repo -v "$PWD":/work -w /work \
|
||||||
|
--entrypoint renovate-config-validator renovate/renovate
|
||||||
|
|
||||||
|
# Woodpecker pipeline
|
||||||
|
docker run --rm -v "$PWD":/work -w /work \
|
||||||
|
woodpeckerci/woodpecker-cli:v3 lint .woodpecker/renovate.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
- [Tailscale: Smaller binaries for embedded devices](https://tailscale.com/docs/how-to/set-up-small-tailscale)
|
- [Tailscale: Smaller binaries for embedded devices](https://tailscale.com/docs/how-to/set-up-small-tailscale)
|
||||||
|
- [Renovate self-hosting](https://docs.renovatebot.com/getting-started/running/)
|
||||||
|
- [Woodpecker cron jobs](https://woodpecker-ci.org/docs/usage/cron)
|
||||||
- [MikroTik Container documentation](https://help.mikrotik.com/docs/display/ROS/Container)
|
- [MikroTik Container documentation](https://help.mikrotik.com/docs/display/ROS/Container)
|
||||||
- [Tailscale subnet routers](https://tailscale.com/kb/1019/subnets)
|
- [Tailscale subnet routers](https://tailscale.com/kb/1019/subnets)
|
||||||
- [Tailscale exit nodes](https://tailscale.com/kb/1103/exit-nodes)
|
- [Tailscale exit nodes](https://tailscale.com/kb/1103/exit-nodes)
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": [
|
||||||
|
"config:recommended",
|
||||||
|
":dependencyDashboard",
|
||||||
|
":semanticCommits"
|
||||||
|
],
|
||||||
|
"labels": ["dependencies"],
|
||||||
|
"rebaseWhen": "behind-base-branch",
|
||||||
|
"dockerfile": {
|
||||||
|
"pinDigests": true
|
||||||
|
},
|
||||||
|
"packageRules": [
|
||||||
|
{
|
||||||
|
"matchDatasources": ["github-releases"],
|
||||||
|
"matchPackageNames": ["tailscale/tailscale"],
|
||||||
|
"description": "TAILSCALE_VERSION ARG: only stable releases. Tailscale uses EVEN minor versions for stable (v1.98.x); ODD minors (v1.99.x) are unstable, so filter to even minors and ignore pre-releases.",
|
||||||
|
"extractVersion": "^v(?<version>\\d+\\.\\d+\\.\\d+)$",
|
||||||
|
"allowedVersions": "/^\\d+\\.\\d*[02468]\\.\\d+$/",
|
||||||
|
"ignoreUnstable": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user