add releases
This commit is contained in:
@@ -0,0 +1,63 @@
|
|||||||
|
# Auto-create the release tag when Tailscale is bumped.
|
||||||
|
#
|
||||||
|
# Policy: a new Tailscale version (merged by Renovate, which edits
|
||||||
|
# ARG TAILSCALE_VERSION in the Dockerfile) gets released as v<ts>-mt.1.
|
||||||
|
# This job runs on every push to main, reads TAILSCALE_VERSION from the
|
||||||
|
# Dockerfile, and — if no v<ts>-mt.* tag exists yet — creates and pushes
|
||||||
|
# v<ts>-mt.1. Pushing that tag triggers .woodpecker/release.yaml.
|
||||||
|
#
|
||||||
|
# Follow-up releases (mt.2, mt.3, ... for manual fixes/changes) are tagged
|
||||||
|
# BY HAND; this job never creates them (it only ever creates -mt.1).
|
||||||
|
#
|
||||||
|
# Dependency-only bumps (Go/Alpine/busybox/dockerfile) leave TAILSCALE_VERSION
|
||||||
|
# unchanged, so no tag is created and nothing is released — they ride along
|
||||||
|
# with the next Tailscale bump or manual tag.
|
||||||
|
|
||||||
|
when:
|
||||||
|
- event: push
|
||||||
|
branch: main
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Get git 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/git_token
|
||||||
|
|
||||||
|
- name: Auto-tag mt.1 on Tailscale bump
|
||||||
|
image: alpine/git:2.49.1
|
||||||
|
environment:
|
||||||
|
CI_REPO_URL: https://gitea.lumpiasty.xyz/lumpiasty/mikrotik-tailscale.git
|
||||||
|
commands:
|
||||||
|
# Read the Tailscale version that's about to be (or was) built.
|
||||||
|
- TS=$(sed -n 's/^ARG TAILSCALE_VERSION=//p' Dockerfile)
|
||||||
|
- 'echo "Tailscale version in Dockerfile: $TS"'
|
||||||
|
- test -n "$TS" || { echo "could not parse TAILSCALE_VERSION"; exit 1; }
|
||||||
|
- TAG="$TS-mt.1"
|
||||||
|
# Make sure we have all tags locally (clone may be shallow / partial).
|
||||||
|
- git fetch --tags --quiet
|
||||||
|
# If ANY release tag already exists for this Tailscale version, the
|
||||||
|
# automatic mt.1 has already happened (or a manual mt.N supersedes it):
|
||||||
|
# do nothing. Only the FIRST sighting of a new Tailscale version tags.
|
||||||
|
- |
|
||||||
|
if git tag --list "$TS-mt.*" | grep -q .; then
|
||||||
|
echo "Release tag(s) already exist for $TS; nothing to auto-tag."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
- echo "No release tag for $TS yet; creating $TAG"
|
||||||
|
- git config user.name "Woodpecker CI"
|
||||||
|
- git config user.email "ci@lumpiasty.xyz"
|
||||||
|
- GIT_TOKEN=$(cat /woodpecker/git_token)
|
||||||
|
# Annotated tag at the current commit.
|
||||||
|
- git tag -a "$TAG" -m "Automated release for Tailscale $TS"
|
||||||
|
- git push "https://woodpecker:$GIT_TOKEN@gitea.lumpiasty.xyz/lumpiasty/mikrotik-tailscale.git" "$TAG"
|
||||||
|
- echo "Pushed $TAG"
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
# Build and publish a multi-arch release to the Gitea container registry.
|
||||||
|
#
|
||||||
|
# Triggered by pushing a v<ts>-mt.<N> tag:
|
||||||
|
# - v<ts>-mt.1 is created automatically by .woodpecker/release-tag.yaml on a
|
||||||
|
# Tailscale bump.
|
||||||
|
# - v<ts>-mt.2, mt.3, ... are created manually for fixes/changes.
|
||||||
|
#
|
||||||
|
# Publishes a SINGLE multi-arch manifest (amd64 + arm64 + arm/v7) so RouterOS
|
||||||
|
# pulls the right arch automatically. Tags pushed:
|
||||||
|
# :<full tag> e.g. v1.98.3-mt.1 (immutable, for rollback/audit)
|
||||||
|
# :stable (moving; what the router tracks)
|
||||||
|
#
|
||||||
|
# The image is stamped with org.opencontainers.image.version=<full tag> via the
|
||||||
|
# OCI_VERSION build arg; the router compares that label to decide updates.
|
||||||
|
#
|
||||||
|
# Registry credentials live in OpenBao (secret/container-registry, keys
|
||||||
|
# REGISTRY_USERNAME / REGISTRY_PASSWORD). The first step fetches them with the
|
||||||
|
# same AppRole used by Renovate and writes them as PLUGIN_USERNAME /
|
||||||
|
# PLUGIN_PASSWORD into an env file that the buildx plugin loads via env_file.
|
||||||
|
# This keeps all secrets in OpenBao (no Woodpecker secret duplication).
|
||||||
|
|
||||||
|
when:
|
||||||
|
- event: tag
|
||||||
|
ref: refs/tags/v*-mt.*
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Get registry creds 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)
|
||||||
|
# Write creds in the env-file format the buildx plugin understands.
|
||||||
|
# PLUGIN_USERNAME / PLUGIN_PASSWORD map to the plugin's username/password.
|
||||||
|
- 'printf "PLUGIN_USERNAME=%s\n" "$(bao kv get -mount secret -field REGISTRY_USERNAME container-registry)" > /woodpecker/registry.env'
|
||||||
|
- 'printf "PLUGIN_PASSWORD=%s\n" "$(bao kv get -mount secret -field REGISTRY_PASSWORD container-registry)" >> /woodpecker/registry.env'
|
||||||
|
|
||||||
|
- name: Build and push multi-arch image
|
||||||
|
image: woodpeckerci/plugin-docker-buildx:5.2.2
|
||||||
|
privileged: true
|
||||||
|
settings:
|
||||||
|
registry: gitea.lumpiasty.xyz
|
||||||
|
repo: gitea.lumpiasty.xyz/lumpiasty/mikrotik-tailscale
|
||||||
|
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||||
|
tags:
|
||||||
|
- ${CI_COMMIT_TAG}
|
||||||
|
- stable
|
||||||
|
build_args:
|
||||||
|
- OCI_VERSION=${CI_COMMIT_TAG}
|
||||||
|
# Credentials (PLUGIN_USERNAME / PLUGIN_PASSWORD) come from OpenBao.
|
||||||
|
env_file: /woodpecker/registry.env
|
||||||
+14
@@ -191,6 +191,20 @@ RUN mkdir -p /rootfs/bin && \
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
FROM scratch
|
FROM scratch
|
||||||
|
|
||||||
|
# Release version (the git tag, e.g. v1.98.3-mt.1), injected by CI at build
|
||||||
|
# time. This is the value the MikroTik update cronjob compares against the
|
||||||
|
# registry to decide whether to recreate the container: it changes ONLY on a
|
||||||
|
# meaningful release (Tailscale bump -> mt.1, or a manual mt.N), never on a
|
||||||
|
# build-system-only rebuild. Defaults to "dev" for local builds.
|
||||||
|
ARG OCI_VERSION=dev
|
||||||
|
|
||||||
|
# OCI image annotations. org.opencontainers.image.version is the canonical place
|
||||||
|
# for the release version and is what the router reads back from the registry.
|
||||||
|
LABEL org.opencontainers.image.title="mikrotik-tailscale" \
|
||||||
|
org.opencontainers.image.description="Minimal Tailscale image for MikroTik RouterOS Container" \
|
||||||
|
org.opencontainers.image.source="https://gitea.lumpiasty.xyz/lumpiasty/mikrotik-tailscale" \
|
||||||
|
org.opencontainers.image.version="${OCI_VERSION}"
|
||||||
|
|
||||||
# Custom static busybox + applet symlinks (provides /bin/sh and utilities)
|
# Custom static busybox + applet symlinks (provides /bin/sh and utilities)
|
||||||
COPY --from=busybox /rootfs/ /
|
COPY --from=busybox /rootfs/ /
|
||||||
|
|
||||||
|
|||||||
@@ -287,6 +287,56 @@ docker buildx build --platform linux/arm64 \
|
|||||||
--load -t mikrotik-tailscale:arm64 .
|
--load -t mikrotik-tailscale:arm64 .
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Versioning & releases
|
||||||
|
|
||||||
|
Released images are versioned as:
|
||||||
|
|
||||||
|
```
|
||||||
|
v<TAILSCALE_VERSION>-mt.<N>
|
||||||
|
```
|
||||||
|
|
||||||
|
e.g. `v1.98.3-mt.1`. The two parts mean:
|
||||||
|
|
||||||
|
- **`v<TAILSCALE_VERSION>`** — the bundled Tailscale version (the "what's
|
||||||
|
inside" identifier), taken from `ARG TAILSCALE_VERSION` in the Dockerfile.
|
||||||
|
- **`mt.<N>`** — the local revision. It only changes on a *meaningful* release,
|
||||||
|
never on a build-system-only rebuild.
|
||||||
|
|
||||||
|
### When a release happens
|
||||||
|
|
||||||
|
| Trigger | Result |
|
||||||
|
|---|---|
|
||||||
|
| Renovate bumps `TAILSCALE_VERSION` (merged to `main`) | CI **auto-creates** git tag `v<new>-mt.1` → image published |
|
||||||
|
| You make a meaningful fix/change on the current Tailscale version | **You** create the next tag manually (`v<ts>-mt.2`, `mt.3`, …) → image published |
|
||||||
|
| Dependency-only bump (Go / Alpine / busybox / Dockerfile syntax) | **No release.** Rides along with the next Tailscale bump or manual tag |
|
||||||
|
|
||||||
|
So routers only ever see a new release for Tailscale bumps or your deliberate
|
||||||
|
fixes — build-system churn doesn't trigger updates.
|
||||||
|
|
||||||
|
Each published image is stamped with `org.opencontainers.image.version` equal to
|
||||||
|
its full tag; this is the value the MikroTik update job compares against the
|
||||||
|
registry to decide whether to recreate the container.
|
||||||
|
|
||||||
|
### How it's wired (Woodpecker)
|
||||||
|
|
||||||
|
- **`.woodpecker/release-tag.yaml`** — on push to `main`, parses
|
||||||
|
`TAILSCALE_VERSION`; if no `v<ts>-mt.*` tag exists yet, creates and pushes
|
||||||
|
`v<ts>-mt.1` (using the Gitea token from OpenBao). It never creates `mt.2+`.
|
||||||
|
- **`.woodpecker/release.yaml`** — on a `v*-mt.*` tag push, builds the
|
||||||
|
multi-arch manifest (amd64 + arm64 + arm/v7) and pushes it to
|
||||||
|
`gitea.lumpiasty.xyz/lumpiasty/mikrotik-tailscale` as both `:<tag>` and
|
||||||
|
`:stable`. Registry creds come from OpenBao (`secret/container-registry`).
|
||||||
|
|
||||||
|
### Cutting a manual release
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# fix something, commit to main, then:
|
||||||
|
git tag -a v1.98.3-mt.2 -m "Fix X"
|
||||||
|
git push origin v1.98.3-mt.2
|
||||||
|
```
|
||||||
|
|
||||||
|
The tag push triggers the build+publish automatically.
|
||||||
|
|
||||||
## Dependency pinning & automated updates
|
## Dependency pinning & automated updates
|
||||||
|
|
||||||
All upstream dependencies are version-pinned for reproducible builds:
|
All upstream dependencies are version-pinned for reproducible builds:
|
||||||
|
|||||||
Reference in New Issue
Block a user