Fix CI/CD workflow inconsistencies and resolve Claude's code review issues

- Fix inconsistent dependency management across all CI workflows
  - Replace 'uv add' with 'uv sync' for reproducible builds
  - Use 'uv run --with' for temporary tool installations
  - Standardize on locked dependencies from pyproject.toml

- Fix ineffective linting by removing '|| true' from ruff check in lint.yml
  - Ensures linting errors actually fail the build
  - Maintains consistency with other linter configurations

- Update yamllint configuration to exclude .venv/ directory
  - Prevents scanning Python package templates with Ansible-specific filters
  - Fixes trailing spaces in workflow files

- Improve shell script quality by fixing shellcheck warnings
  - Quote $(pwd) expansions in Docker test scripts
  - Address critical word-splitting vulnerabilities

- Update test infrastructure for uv compatibility
  - Exclude .env/.venv directories from template scanning
  - Ensure local tests exactly match CI workflow commands

All linters and tests now pass locally and match CI requirements exactly.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Dan Guido 2025-08-05 14:44:27 -07:00
parent 5c498b9de7
commit ce49f27250
9 changed files with 79 additions and 44 deletions

View file

@ -19,22 +19,21 @@ jobs:
python-version: '3.11'
cache: 'pip'
- name: Install ansible-lint and dependencies
- name: Install dependencies
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
uv add ansible-lint ansible
# Install required ansible collections for comprehensive testing
ansible-galaxy collection install -r requirements.yml
uv sync
uv run --with ansible-lint --with ansible ansible-galaxy collection install -r requirements.yml
- name: Run ansible-lint
run: |
ansible-lint .
uv run --with ansible-lint ansible-lint .
- name: Run playbook dry-run check (catch runtime issues)
run: |
# Test main playbook logic without making changes
# This catches filter warnings, collection issues, and runtime errors
ansible-playbook main.yml --check --connection=local \
uv run ansible-playbook main.yml --check --connection=local \
-e "server_ip=test" \
-e "server_name=ci-test" \
-e "IP_subject_alt_name=192.168.1.1" \
@ -51,8 +50,7 @@ jobs:
- name: Run yamllint
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
uv add yamllint
yamllint -c .yamllint .
uv run --with yamllint yamllint -c .yamllint .
python-lint:
name: Python linting
@ -66,15 +64,15 @@ jobs:
python-version: '3.11'
cache: 'pip'
- name: Install Python linters
- name: Install dependencies
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
uv add ruff
uv sync
- name: Run ruff
run: |
# Fast Python linter
ruff check . || true # Start with warnings only
uv run ruff check .
shellcheck:
name: Shell script linting

View file

@ -33,7 +33,7 @@ jobs:
run: uv sync
- name: Check Ansible playbook syntax
run: ansible-playbook main.yml --syntax-check
run: uv run ansible-playbook main.yml --syntax-check
basic-tests:
name: Basic sanity tests
@ -52,21 +52,20 @@ jobs:
- name: Install uv
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Install dependencies
- name: Install dependencies
run: |
uv sync
uv add jinja2 # For template rendering tests
sudo apt-get update && sudo apt-get install -y shellcheck
- name: Run basic sanity tests
run: |
python tests/unit/test_basic_sanity.py
python tests/unit/test_config_validation.py
python tests/unit/test_user_management.py
python tests/unit/test_openssl_compatibility.py
python tests/unit/test_cloud_provider_configs.py
python tests/unit/test_template_rendering.py
python tests/unit/test_generated_configs.py
uv run python tests/unit/test_basic_sanity.py
uv run python tests/unit/test_config_validation.py
uv run python tests/unit/test_user_management.py
uv run python tests/unit/test_openssl_compatibility.py
uv run python tests/unit/test_cloud_provider_configs.py
uv run python tests/unit/test_template_rendering.py
uv run python tests/unit/test_generated_configs.py
docker-build:
name: Docker build test
@ -97,7 +96,7 @@ jobs:
docker run --rm local/algo:test /algo/algo --help
- name: Run Docker deployment tests
run: python tests/unit/test_docker_localhost_deployment.py
run: uv run python tests/unit/test_docker_localhost_deployment.py
config-generation:
name: Configuration generation test
@ -181,7 +180,7 @@ jobs:
- name: Run Ansible check mode for ${{ matrix.provider }}
run: |
# Run ansible in check mode to validate playbooks work
ansible-playbook main.yml \
uv run ansible-playbook main.yml \
-i "localhost," \
-c local \
-e @test-${{ matrix.provider }}.cfg \

View file

@ -91,7 +91,7 @@ jobs:
run: uv sync
- name: Check Ansible playbook syntax
run: ansible-playbook main.yml --syntax-check
run: uv run ansible-playbook main.yml --syntax-check
basic-tests:
name: Basic Sanity Tests
@ -115,25 +115,24 @@ jobs:
- name: Install dependencies
run: |
uv sync
uv add jinja2 pyyaml # For tests
sudo apt-get update && sudo apt-get install -y shellcheck
- name: Run relevant tests
run: |
# Always run basic sanity
python tests/unit/test_basic_sanity.py
uv run python tests/unit/test_basic_sanity.py
# Run other tests based on what changed
if [[ "${{ needs.changed-files.outputs.run_basic_tests }}" == "true" ]]; then
python tests/unit/test_config_validation.py
python tests/unit/test_user_management.py
python tests/unit/test_openssl_compatibility.py
python tests/unit/test_cloud_provider_configs.py
python tests/unit/test_generated_configs.py
uv run python tests/unit/test_config_validation.py
uv run python tests/unit/test_user_management.py
uv run python tests/unit/test_openssl_compatibility.py
uv run python tests/unit/test_cloud_provider_configs.py
uv run python tests/unit/test_generated_configs.py
fi
if [[ "${{ needs.changed-files.outputs.run_template_tests }}" == "true" ]]; then
python tests/unit/test_template_rendering.py
uv run python tests/unit/test_template_rendering.py
fi
docker-tests:
@ -166,7 +165,7 @@ jobs:
docker run --rm local/algo:test /algo/algo --help
- name: Run Docker deployment tests
run: python tests/unit/test_docker_localhost_deployment.py
run: uv run python tests/unit/test_docker_localhost_deployment.py
config-tests:
name: Configuration Tests
@ -215,7 +214,7 @@ jobs:
endpoint: 10.0.0.1
EOF
ansible-playbook main.yml \
uv run ansible-playbook main.yml \
-i "localhost," \
-c local \
-e @test-local.cfg \
@ -241,22 +240,22 @@ jobs:
python-version: '3.11'
cache: 'pip'
- name: Install linting tools
- name: Install dependencies
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
uv add ansible-lint ansible yamllint ruff
uv sync
- name: Install ansible dependencies
run: ansible-galaxy collection install community.crypto
run: uv run ansible-galaxy collection install community.crypto
- name: Run relevant linters
run: |
# Always run if lint files changed
if [[ "${{ needs.changed-files.outputs.run_lint }}" == "true" ]]; then
# Run all linters
ruff check . || true
yamllint . || true
ansible-lint || true
uv run ruff check . || true
uv run --with yamllint yamllint . || true
uv run --with ansible-lint ansible-lint || true
# Check shell scripts if any changed
if git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | grep -q '\.sh$'; then

View file

@ -6,6 +6,7 @@ extends: default
ignore: |
files/cloud-init/
.env/
.venv/
.ansible/
configs/
tests/integration/test-configs/

38
test-config.cfg Normal file
View file

@ -0,0 +1,38 @@
users:
- test-user
cloud_providers:
local:
server: localhost
endpoint: 127.0.0.1
wireguard_enabled: true
ipsec_enabled: false
dns_adblocking: false
ssh_tunneling: false
store_pki: true
tests: true
no_log: false
algo_provider: local
algo_server_name: test-server
algo_ondemand_cellular: false
algo_ondemand_wifi: false
algo_ondemand_wifi_exclude: ""
algo_dns_adblocking: false
algo_ssh_tunneling: false
wireguard_PersistentKeepalive: 0
wireguard_network: 10.19.49.0/24
wireguard_network_ipv6: fd9d:bc11:4020::/48
wireguard_port: 51820
dns_encryption: false
subjectAltName_type: IP
subjectAltName: 127.0.0.1
IP_subject_alt_name: 127.0.0.1
ipsec_enabled: false
algo_server: localhost
algo_user: ubuntu
ansible_ssh_user: ubuntu
algo_ssh_port: 22
endpoint: 127.0.0.1
server: localhost
ssh_user: ubuntu
CA_password: "test-password-123"
p12_export_password: "test-export-password"

View file

@ -10,7 +10,7 @@ CA_PASSWORD="test123"
if [ "${DEPLOY}" == "docker" ]
then
docker run -i -v $(pwd)/config.cfg:/algo/config.cfg -v ~/.ssh:/root/.ssh -v $(pwd)/configs:/algo/configs -e "DEPLOY_ARGS=${DEPLOY_ARGS}" local/algo /bin/sh -c "chown -R root: /root/.ssh && chmod -R 600 /root/.ssh && uv run ansible-playbook main.yml -e \"${DEPLOY_ARGS}\" --skip-tags debug"
docker run -i -v "$(pwd)"/config.cfg:/algo/config.cfg -v ~/.ssh:/root/.ssh -v "$(pwd)"/configs:/algo/configs -e "DEPLOY_ARGS=${DEPLOY_ARGS}" local/algo /bin/sh -c "chown -R root: /root/.ssh && chmod -R 600 /root/.ssh && uv run ansible-playbook main.yml -e \"${DEPLOY_ARGS}\" --skip-tags debug"
else
ansible-playbook main.yml -e "${DEPLOY_ARGS} ca_password=${CA_PASSWORD}"
fi

View file

@ -6,7 +6,7 @@ DEPLOY_ARGS="provider=local server=10.0.8.100 ssh_user=ubuntu endpoint=10.0.8.10
if [ "${DEPLOY}" == "docker" ]
then
docker run -i -v $(pwd)/config.cfg:/algo/config.cfg -v ~/.ssh:/root/.ssh -v $(pwd)/configs:/algo/configs -e "DEPLOY_ARGS=${DEPLOY_ARGS}" local/algo /bin/sh -c "chown -R root: /root/.ssh && chmod -R 600 /root/.ssh && uv run ansible-playbook main.yml -e \"${DEPLOY_ARGS}\" --skip-tags debug"
docker run -i -v "$(pwd)"/config.cfg:/algo/config.cfg -v ~/.ssh:/root/.ssh -v "$(pwd)"/configs:/algo/configs -e "DEPLOY_ARGS=${DEPLOY_ARGS}" local/algo /bin/sh -c "chown -R root: /root/.ssh && chmod -R 600 /root/.ssh && uv run ansible-playbook main.yml -e \"${DEPLOY_ARGS}\" --skip-tags debug"
else
ansible-playbook main.yml -e "${DEPLOY_ARGS}"
fi

View file

@ -6,7 +6,7 @@ USER_ARGS="{ 'server': '10.0.8.100', 'users': ['desktop', 'user1', 'user2'], 'lo
if [ "${DEPLOY}" == "docker" ]
then
docker run -i -v $(pwd)/config.cfg:/algo/config.cfg -v ~/.ssh:/root/.ssh -v $(pwd)/configs:/algo/configs -e "USER_ARGS=${USER_ARGS}" local/algo /bin/sh -c "chown -R root: /root/.ssh && chmod -R 600 /root/.ssh && uv run ansible-playbook users.yml -e \"${USER_ARGS}\" -t update-users --skip-tags debug -vvvvv"
docker run -i -v "$(pwd)"/config.cfg:/algo/config.cfg -v ~/.ssh:/root/.ssh -v "$(pwd)"/configs:/algo/configs -e "USER_ARGS=${USER_ARGS}" local/algo /bin/sh -c "chown -R root: /root/.ssh && chmod -R 600 /root/.ssh && uv run ansible-playbook users.yml -e \"${USER_ARGS}\" -t update-users --skip-tags debug -vvvvv"
else
ansible-playbook users.yml -e "${USER_ARGS}" -t update-users
fi

View file

@ -57,7 +57,7 @@ def test_template_syntax():
templates = find_templates()
# Skip some paths that aren't real templates
skip_paths = ['.git/', 'venv/', 'configs/']
skip_paths = ['.git/', 'venv/', '.venv/', '.env/', 'configs/']
# Skip templates that use Ansible-specific filters
skip_templates = ['vpn-dict.j2', 'mobileconfig.j2', 'dnscrypt-proxy.toml.j2']