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
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
10 changes: 3 additions & 7 deletions .github/workflows/hadolint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,9 @@ jobs:
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- name: Run hadolint
uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0
with:
dockerfile: ./Dockerfile
format: sarif
output-file: hadolint-results.sarif
no-fail: true
- name: Run hadolint via Makefile
continue-on-error: true
run: make lint-docker HADOLINT_FORMAT=sarif HADOLINT_OUTPUT_FILE=hadolint-results.sarif

- name: Upload analysis results to GitHub
uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
Expand Down
101 changes: 17 additions & 84 deletions .github/workflows/headscale-config-checker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,100 +17,33 @@ jobs:
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- 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: Generate config from template with defaults
run: |
# Source the defaults
source scripts/defaults.sh
source scripts/ci-defaults.sh

# Generate config
envsubst < templates/headscale.template.yaml > generated-config.yaml

- name: Check for new options
- name: Check for new options via Makefile
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" "templates/headscale.template.yaml" | \
sed -E 's/^[[:space:]]*#?[[:space:]]*//' | \
sed -E 's/:.*# DIFF_IGNORE.*$//' | \
sort -u
}

echo "=== Getting ignored keys ==="
get_ignored_keys > ignored_keys.txt
echo "Keys to ignore:"
cat ignored_keys.txt
echo "=== End ignored keys ==="

# Extract all keys
extract_keys "generated-config.yaml" > local_all_keys.txt
extract_keys "upstream-config.yaml" > upstream_all_keys.txt

# Normalize keys (strip optional leading '#' and surrounding spaces) and sort-unique
sed -E 's/^[[:space:]]*#?[[:space:]]*//' upstream_all_keys.txt | sed 's/[[:space:]]*$//' | sort -u > upstream_all_keys_norm.txt
sed -E 's/^[[:space:]]*#?[[:space:]]*//' local_all_keys.txt | sed 's/[[:space:]]*$//' | sort -u > local_all_keys_norm.txt

# Remove ignored keys from upstream (operate on normalized list)
cp upstream_all_keys_norm.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

# Ensure upstream filtered file is sorted/unique for comm
sort -u upstream_filtered_keys.txt -o upstream_filtered_keys.txt

# Find missing keys using normalized local list
comm -23 upstream_filtered_keys.txt local_all_keys_norm.txt > new-options.txt

echo "Final comparison:"
echo "Local keys: $(wc -l < local_all_keys_norm.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 upstream_all_keys_norm.txt local_all_keys_norm.txt
continue-on-error: true
run: make check-config-drift

- name: Comment on PR
if: github.event_name == 'pull_request' && steps.check.outputs.has_missing == 'true'
if: github.event_name == 'pull_request' && steps.check.outcome == 'failure' && hashFiles('new-options.txt') != ''
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
Comment thread
EdGeraghty marked this conversation as resolved.
const fs = require('fs');
if (!fs.existsSync('new-options.txt')) {
console.log('Skipping PR comment because new-options.txt was not created.');
return;
}

const newOptions = fs.readFileSync('new-options.txt', 'utf8');
github.rest.issues.createComment({

await 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')}\`\`\``
});

- name: Fail when drift check fails
if: steps.check.outcome == 'failure'
run: |
echo 'Headscale config drift check failed (see logs above).'
exit 1
Loading