Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions .github/workflows/headscale-config-checker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: Check for New (upstream) Headscale Config Options

on:
pull_request:
push:
branches: [ "main", "develop" ]
workflow_dispatch:

jobs:
check-missing-options:
runs-on: ubuntu-latest
permissions:
pull-requests: write

steps:
- uses: actions/checkout@v4

- name: Get version and download upstream config
run: |
VERSION=$(grep -oP 'HEADSCALE_VERSION="\K[^"]*' Dockerfile)
echo "Found version: $VERSION"

curl -f -o upstream-config.yaml \
"https://raw.githubusercontent.com/juanfont/headscale/refs/tags/v${VERSION}/config-example.yaml"

echo "Successfully downloaded upstream config"

- name: Check for new options
id: check
run: |
# Simple approach: extract keys and apply ignores
extract_keys() {
grep -E "^[[:space:]]*[^#].*:" "$1" | \
sed 's/:[[:space:]]*.*$//' | \
sed 's/^[[:space:]]*//' | \
sort -u
}

# Get list of keys to ignore from DIFF_IGNORE comments (including commented lines)
get_ignored_keys() {
grep "# DIFF_IGNORE" "$1" | \
sed -E 's/^[[:space:]]*#?[[:space:]]*//' | \
sed -E 's/:.*# DIFF_IGNORE.*$//' | \
sort -u
}

echo "=== Getting ignored keys ==="
get_ignored_keys "templates/headscale.template.yaml" > ignored_keys.txt
echo "Keys to ignore:"
cat ignored_keys.txt
echo "=== End ignored keys ==="

# Extract all keys
extract_keys "templates/headscale.template.yaml" > local_all_keys.txt
extract_keys "upstream-config.yaml" > upstream_all_keys.txt

# Remove ignored keys from upstream
cp upstream_all_keys.txt upstream_filtered_keys.txt
while IFS= read -r ignore_key; do
if [ -n "$ignore_key" ]; then
grep -v "^${ignore_key}$" upstream_filtered_keys.txt > temp_filtered.txt
mv temp_filtered.txt upstream_filtered_keys.txt
fi
done < ignored_keys.txt

# Find missing keys
comm -23 upstream_filtered_keys.txt local_all_keys.txt > new-options.txt

echo "Final comparison:"
echo "Local keys: $(wc -l < local_all_keys.txt)"
echo "Upstream filtered keys: $(wc -l < upstream_filtered_keys.txt)"

if [ -s new-options.txt ]; then
echo "has_missing=true" >> $GITHUB_OUTPUT
echo "🆕 New configuration keys found:"
cat new-options.txt
else
echo "has_missing=false" >> $GITHUB_OUTPUT
echo "✅ No new configuration keys found"
fi

# Cleanup
rm -f ignored_keys.txt local_all_keys.txt upstream_all_keys.txt upstream_filtered_keys.txt temp_filtered.txt

- name: Comment on PR
if: github.event_name == 'pull_request' && steps.check.outputs.has_missing == 'true'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const newOptions = fs.readFileSync('new-options.txt', 'utf8');

github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `## 🆕 New Headscale Config Options\n\n\`\`\`diff\n${newOptions.split('\n').map(line => line.trim() ? `+ ${line}` : '').filter(line => line).join('\n')}\`\`\``
});
54 changes: 20 additions & 34 deletions templates/headscale.template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,10 @@ server_url: https://$PUBLIC_SERVER_URL:$PUBLIC_LISTEN_PORT
# listen_addr: 0.0.0.0:8080
listen_addr: 127.0.0.1:8080

# Address to listen to /metrics, you may want
# to keep this endpoint private to your internal
# network
#
# Address to listen to /metrics and /debug, you may want
# to keep this endpoint private to your internal network
metrics_listen_addr: 127.0.0.1:9090

# Private key used to encrypt the traffic between headscale and Tailscale clients.
# The private key file will be autogenerated if it's missing, or filled from an
# environment variable if set
private_key_path: /data/private.key
# Address to listen for gRPC.
# gRPC is used for controlling a headscale server
# remotely with the CLI
Expand All @@ -44,11 +38,12 @@ grpc_listen_addr: 127.0.0.1:50443
# are doing.
grpc_allow_insecure: false

# The Noise section includes specific configuration for the TS2021 Noise protocol
# The Noise section includes specific configuration for the
# TS2021 Noise protocol
noise:
# The Noise private key is used to encrypt the
# traffic between headscale and Tailscale clients when
# using the new Noise-based protocol.
# The Noise private key is used to encrypt the traffic between headscale and
# Tailscale clients when using the new Noise-based protocol. A missing key
# will be automatically generated.
private_key_path: /data/noise_private.key

# List of IP prefixes to allocate tailaddresses from.
Expand Down Expand Up @@ -169,7 +164,6 @@ database:

# Enable WAL mode for SQLite. This is recommended for production environments.
# https://www.sqlite.org/wal.html
# _DISABLE IF USING NFS_
write_ahead_log: true

# Maximum number of WAL file frames before the WAL file is automatically checkpointed.
Expand Down Expand Up @@ -203,27 +197,27 @@ database:
# TLS for a domain with Let's Encrypt.
#
# URL to ACME directory
#acme_url: https://acme-v02.api.letsencrypt.org/directory
#acme_url: https://acme-v02.api.letsencrypt.org/directory # DIFF_IGNORE

# Email to register with ACME provider
#acme_email: ""
#acme_email: "" # DIFF_IGNORE

# Domain name to request a TLS certificate for:
#tls_letsencrypt_hostname: ""
#tls_letsencrypt_hostname: "" # DIFF_IGNORE

# Path to store certificates and metadata needed by
# letsencrypt
# For production:
#tls_letsencrypt_cache_dir: /var/lib/headscale/cache
#tls_letsencrypt_cache_dir: /var/lib/headscale/cache # DIFF_IGNORE

# Type of ACME challenge to use, currently supported types:
# HTTP-01 or TLS-ALPN-01
# See: docs/ref/tls.md for more information
#tls_letsencrypt_challenge_type: HTTP-01
#tls_letsencrypt_challenge_type: HTTP-01 # DIFF_IGNORE
# When HTTP-01 challenge is chosen, letsencrypt must set up a
# verification endpoint, and it will be listening on:
# :http = port 80
#tls_letsencrypt_listen: ":http"
#tls_letsencrypt_listen: ":http" # DIFF_IGNORE

## Use already defined certificates:
tls_cert_path: ""
Expand All @@ -236,14 +230,15 @@ log:

## Policy
# headscale supports Tailscale's ACL policies.
# Please have a look to their KB to better understand the concepts: https://tailscale.com/kb/1018/acls/
# Please have a look to their KB to better
# understand the concepts: https://tailscale.com/kb/1018/acls/
policy:
# The mode can be "file" or "database" that defines
# where the ACL policies are stored and read from.
mode: database
# If the mode is set to "file", the path to a
# HuJSON file containing ACL policies.
# path: ""
# path: "" # DIFF_IGNORE

## DNS
#
Expand Down Expand Up @@ -277,6 +272,10 @@ dns:
# `hostname.base_domain` (e.g., _myhost.example.com_).
base_domain: $HEADSCALE_DNS_CONFIG_BASE_DOMAIN

# Whether to use the local DNS settings of a node (default) or override the
# local DNS settings and force the use of Headscale's DNS configuration.
override_local_dns: false

# List of DNS servers to expose to clients.
nameservers:
global:
Expand Down Expand Up @@ -379,19 +378,6 @@ oidc:
# # - plain: Use plain code verifier
# # - S256: Use SHA256 hashed code verifier (default, recommended)
# method: S256
#
# # Map legacy users from pre-0.24.0 versions of headscale to the new OIDC users
# # by taking the username from the legacy user and matching it with the username
# # provided by the OIDC. This is useful when migrating from legacy users to OIDC
# # to force them using the unique identifier from the OIDC and to give them a
# # proper display name and picture if available.
# # Note that this will only work if the username from the legacy user is the same
# # and there is a possibility for account takeover should a username have changed
# # with the provider.
# # When this feature is disabled, it will cause all new logins to be created as new users.
# # Note this option will be removed in the future and should be set to false
# # on all new installations, or when all users have logged in with OIDC once.
# map_legacy_users: false

# Logtail configuration
# Logtail is Tailscales logging and auditing infrastructure, it allows the control panel
Expand Down
Loading