mirror of
https://github.com/juanfont/headscale.git
synced 2026-05-23 18:48:42 +09:00
Fork PRs anonymous-pull tailscale/tailscale:vX.Y at test time and hit Docker Hub rate limits, causing flakes. A new build-tailscale-released job pulls the MustTestVersions set from ghcr.io once per CI run and ships them to every test job as a gzipped tarball artifact, matching the shape of the existing headscale/HEAD/postgres caches. The version list is driven by 'hi list-versions' so capver is the single source of truth; adding a version there propagates to CI without YAML edits. ghcr.io public reads need no auth, so the new job has no docker login step.
140 lines
6.0 KiB
YAML
140 lines
6.0 KiB
YAML
name: Integration Test Template
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
test:
|
|
required: true
|
|
type: string
|
|
postgres_flag:
|
|
required: false
|
|
type: string
|
|
default: ""
|
|
database_name:
|
|
required: true
|
|
type: string
|
|
|
|
jobs:
|
|
test:
|
|
runs-on: ubuntu-24.04-arm
|
|
env:
|
|
# Github does not allow us to access secrets in pull requests,
|
|
# so this env var is used to check if we have the secret or not.
|
|
# If we have the secrets, meaning we are running on push in a fork,
|
|
# there might be secrets available for more debugging.
|
|
# If TS_OAUTH_CLIENT_ID and TS_OAUTH_SECRET is set, then the job
|
|
# will join a debug tailscale network, set up SSH and a tmux session.
|
|
# The SSH will be configured to use the SSH key of the Github user
|
|
# that triggered the build.
|
|
HAS_TAILSCALE_SECRET: ${{ secrets.TS_OAUTH_CLIENT_ID }}
|
|
steps:
|
|
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
|
with:
|
|
fetch-depth: 2
|
|
- name: Tailscale
|
|
if: ${{ env.HAS_TAILSCALE_SECRET }}
|
|
uses: tailscale/github-action@a392da0a182bba0e9613b6243ebd69529b1878aa # v4.1.0
|
|
with:
|
|
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
|
|
oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
|
|
tags: tag:gh
|
|
- name: Setup SSH server for Actor
|
|
if: ${{ env.HAS_TAILSCALE_SECRET }}
|
|
uses: alexellis/setup-sshd-actor@master
|
|
- name: Download headscale image
|
|
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
|
with:
|
|
name: headscale-image
|
|
path: /tmp/artifacts
|
|
- name: Download tailscale HEAD image
|
|
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
|
with:
|
|
name: tailscale-head-image
|
|
path: /tmp/artifacts
|
|
- name: Download tailscale released images
|
|
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
|
with:
|
|
name: tailscale-released-images
|
|
path: /tmp/artifacts
|
|
- name: Download hi binary
|
|
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
|
with:
|
|
name: hi-binary
|
|
path: /tmp/artifacts
|
|
- name: Download Go cache
|
|
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
|
with:
|
|
name: go-cache
|
|
path: /tmp/artifacts
|
|
- name: Download postgres image
|
|
if: ${{ inputs.postgres_flag == '--postgres=1' }}
|
|
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
|
with:
|
|
name: postgres-image
|
|
path: /tmp/artifacts
|
|
- name: Force overlay2 storage driver
|
|
run: |
|
|
sudo mkdir -p /etc/docker
|
|
echo '{"storage-driver":"overlay2"}' | sudo tee /etc/docker/daemon.json
|
|
sudo systemctl restart docker
|
|
docker version
|
|
- name: Login to Docker Hub
|
|
env:
|
|
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_CI_USERNAME }}
|
|
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_CI_TOKEN }}
|
|
if: env.DOCKERHUB_USERNAME != ''
|
|
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
|
with:
|
|
username: ${{ env.DOCKERHUB_USERNAME }}
|
|
password: ${{ env.DOCKERHUB_TOKEN }}
|
|
- name: Load Docker images, Go cache, and prepare binary
|
|
run: |
|
|
gunzip -c /tmp/artifacts/headscale-image.tar.gz | docker load
|
|
gunzip -c /tmp/artifacts/tailscale-head-image.tar.gz | docker load
|
|
gunzip -c /tmp/artifacts/tailscale-released-images.tar.gz | docker load
|
|
if [ -f /tmp/artifacts/postgres-image.tar.gz ]; then
|
|
gunzip -c /tmp/artifacts/postgres-image.tar.gz | docker load
|
|
fi
|
|
chmod +x /tmp/artifacts/hi
|
|
docker images
|
|
# Extract Go cache to host directories for bind mounting
|
|
mkdir -p /tmp/go-cache
|
|
tar -xzf /tmp/artifacts/go-cache.tar.gz -C /tmp/go-cache
|
|
ls -la /tmp/go-cache/ /tmp/go-cache/.cache/
|
|
- name: Run Integration Test
|
|
env:
|
|
HEADSCALE_INTEGRATION_HEADSCALE_IMAGE: headscale:${{ github.sha }}
|
|
HEADSCALE_INTEGRATION_TAILSCALE_IMAGE: tailscale-head:${{ github.sha }}
|
|
HEADSCALE_INTEGRATION_POSTGRES_IMAGE: ${{ inputs.postgres_flag == '--postgres=1' && format('postgres:{0}', github.sha) || '' }}
|
|
HEADSCALE_INTEGRATION_GO_CACHE: /tmp/go-cache/go
|
|
HEADSCALE_INTEGRATION_GO_BUILD_CACHE: /tmp/go-cache/.cache/go-build
|
|
# Mirror the docker/login-action secrets into env so the
|
|
# dockertestutil.Credentials resolver picks them up directly
|
|
# (otherwise it falls back to parsing ~/.docker/config.json,
|
|
# which works but is one step further from the source).
|
|
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_CI_USERNAME }}
|
|
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_CI_TOKEN }}
|
|
run: /tmp/artifacts/hi run --stats --ts-memory-limit=300 --hs-memory-limit=1500 "^${{ inputs.test }}$" \
|
|
--timeout=120m \
|
|
${{ inputs.postgres_flag }}
|
|
# Sanitize test name for artifact upload (replace invalid characters: " : < > | * ? \ / with -)
|
|
- name: Sanitize test name for artifacts
|
|
if: always()
|
|
id: sanitize
|
|
run: echo "name=${TEST_NAME//[\":<>|*?\\\/]/-}" >> $GITHUB_OUTPUT
|
|
env:
|
|
TEST_NAME: ${{ inputs.test }}
|
|
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
|
if: always()
|
|
with:
|
|
name: ${{ inputs.database_name }}-${{ steps.sanitize.outputs.name }}-logs
|
|
path: "control_logs/*/*.log"
|
|
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
|
if: always()
|
|
with:
|
|
name: ${{ inputs.database_name }}-${{ steps.sanitize.outputs.name }}-artifacts
|
|
path: control_logs/
|
|
- name: Setup a blocking tmux session
|
|
if: ${{ env.HAS_TAILSCALE_SECRET }}
|
|
uses: alexellis/block-with-tmux-action@master
|