Pull Request by @renovate[bot] #161
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| name: Pull Request | |
| run-name: Pull Request by @${{ github.actor }} | |
| on: | |
| pull_request: | |
| branches: [main] | |
| types: [opened, synchronize, reopened, ready_for_review] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| security-events: write | |
| actions: read | |
| pull-requests: write | |
| issues: read | |
| id-token: write | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| ANSIBLE_FORCE_COLOR: "true" | |
| PY_COLORS: "1" | |
| GOPROXY: "https://proxy.golang.org,direct" | |
| jobs: | |
| ci: | |
| uses: arillso/.github/.github/workflows/ci-go.yml@2026-08-27 | |
| lint: | |
| uses: arillso/.github/.github/workflows/ci-lint.yml@2026-08-27 | |
| with: | |
| enable_shellcheck: true | |
| security-secrets: | |
| uses: arillso/.github/.github/workflows/security-secrets.yml@2026-08-27 | |
| security-deps: | |
| uses: arillso/.github/.github/workflows/security-deps.yml@2026-08-27 | |
| claude-review: | |
| uses: arillso/.github/.github/workflows/ai-claude-review.yml@2026-08-27 | |
| secrets: | |
| CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | |
| setup-environment: | |
| name: Setup Environment | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| outputs: | |
| cache-key: ${{ steps.cache-key.outputs.key }} | |
| test-level: ${{ steps.test-config.outputs.level }} | |
| go-version: ${{ steps.versions.outputs.go }} | |
| ansible-version: ${{ steps.versions.outputs.ansible }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Determine versions | |
| id: versions | |
| run: | | |
| GO_VERSION=$(grep '^go ' go.mod | cut -d' ' -f2) | |
| ANSIBLE_VERSION=$(grep 'FROM arillso/ansible:' Dockerfile | cut -d':' -f2 | cut -d'@' -f1) | |
| echo "go=${GO_VERSION}" >> "$GITHUB_OUTPUT" | |
| echo "ansible=${ANSIBLE_VERSION}" >> "$GITHUB_OUTPUT" | |
| - name: Configure test level | |
| id: test-config | |
| run: | | |
| if [[ "${{ github.event_name }}" == "pull_request" ]]; then | |
| echo "level=basic" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "level=full" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Generate cache key | |
| id: cache-key | |
| run: | | |
| echo "key=action-tests-${{ hashFiles('**/go.sum', 'Dockerfile', 'tests/**/*', 'action.yml') }}" >> "$GITHUB_OUTPUT" | |
| build-action: | |
| name: Build Action | |
| needs: setup-environment | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup Go | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 | |
| with: | |
| go-version: ${{ needs.setup-environment.outputs.go-version }} | |
| cache: true | |
| - name: Build Go binary | |
| run: | | |
| go build -ldflags="-s -w" -o action-playbook . | |
| - name: Cache built binary | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 | |
| with: | |
| path: action-playbook | |
| key: ${{ needs.setup-environment.outputs.cache-key }}-binary | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4 | |
| - name: Build Docker image | |
| uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7 | |
| with: | |
| context: . | |
| push: false | |
| load: true | |
| tags: action-playbook:test | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Update action.yml for testing | |
| run: | | |
| sed -i 's|image: ".*"|image: "docker://action-playbook:test"|' action.yml | |
| - name: Test binary execution | |
| run: | | |
| ./action-playbook --help | |
| test-basic: | |
| name: Basic Function Test | |
| needs: [setup-environment, build-action] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup test image | |
| uses: ./.github/actions/setup-test-image | |
| - name: Run basic playbook | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| galaxy_file: tests/requirements.yml | |
| execution_timeout: 10 | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| test-advanced: | |
| name: Advanced Playbook Test | |
| needs: [setup-environment, test-basic] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup test image | |
| uses: ./.github/actions/setup-test-image | |
| - name: Run advanced playbook | |
| uses: ./ | |
| with: | |
| playbook: tests/advanced_playbook.yml | |
| inventory: tests/hosts.yml | |
| galaxy_file: tests/requirements.yml | |
| execution_timeout: 15 | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| test-modes: | |
| name: Test Execution Modes | |
| needs: [setup-environment, test-basic] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| strategy: | |
| matrix: | |
| mode: [check, diff, syntax_check, verbose] | |
| fail-fast: false | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup test image | |
| uses: ./.github/actions/setup-test-image | |
| - name: Run with ${{ matrix.mode }} mode | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| galaxy_file: tests/requirements.yml | |
| check: ${{ matrix.mode == 'check' }} | |
| diff: ${{ matrix.mode == 'diff' }} | |
| syntax_check: ${{ matrix.mode == 'syntax_check' }} | |
| verbose: ${{ matrix.mode == 'verbose' && '3' || '' }} | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| test-parameters: | |
| name: Test Parameters | |
| needs: [setup-environment, test-basic] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup test image | |
| uses: ./.github/actions/setup-test-image | |
| - name: Test with tags | |
| uses: ./ | |
| with: | |
| playbook: tests/tagged_playbook.yml | |
| inventory: tests/hosts.yml | |
| galaxy_file: tests/requirements.yml | |
| tags: "tag1" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Test with skip-tags | |
| uses: ./ | |
| with: | |
| playbook: tests/tagged_playbook.yml | |
| inventory: tests/hosts.yml | |
| galaxy_file: tests/requirements.yml | |
| skip_tags: "tag2" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Test with extra-vars | |
| uses: ./ | |
| with: | |
| playbook: tests/extra_vars_playbook.yml | |
| inventory: tests/hosts.yml | |
| galaxy_file: tests/requirements.yml | |
| extra_vars: "my_var=test_value env_var=from_extra_vars" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Test with limit hosts | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| galaxy_file: tests/requirements.yml | |
| limit: "localhost" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| test-ssh-key-handling: | |
| name: SSH Key Format Tests | |
| needs: [setup-environment, test-basic] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup test image | |
| uses: ./.github/actions/setup-test-image | |
| - name: Generate test SSH key (Unix LF format) | |
| run: | | |
| ssh-keygen -t rsa -b 2048 -f /tmp/test_key_lf -N "" -C "test@example.com" | |
| { | |
| echo "TEST_KEY_LF<<EOF" | |
| cat /tmp/test_key_lf | |
| echo "" | |
| echo "EOF" | |
| } >> "$GITHUB_ENV" | |
| - name: Generate test SSH key (Windows CRLF format) | |
| run: | | |
| ssh-keygen -t rsa -b 2048 -f /tmp/test_key_crlf -N "" -C "test@example.com" | |
| # Convert LF to CRLF (Windows line endings) | |
| sed -i 's/$/\r/' /tmp/test_key_crlf | |
| { | |
| echo "TEST_KEY_CRLF<<EOF" | |
| cat /tmp/test_key_crlf | |
| echo "" | |
| echo "EOF" | |
| } >> "$GITHUB_ENV" | |
| - name: Generate test SSH key (No trailing newline) | |
| run: | | |
| ssh-keygen -t rsa -b 2048 -f /tmp/test_key_no_newline -N "" -C "test@example.com" | |
| # Remove trailing newline | |
| truncate -s -1 /tmp/test_key_no_newline | |
| { | |
| echo "TEST_KEY_NO_NEWLINE<<EOF" | |
| cat /tmp/test_key_no_newline | |
| echo "" | |
| echo "EOF" | |
| } >> "$GITHUB_ENV" | |
| - name: Test with LF formatted key | |
| uses: ./ | |
| with: | |
| playbook: tests/ssh_key_test_playbook.yml | |
| inventory: tests/hosts.yml | |
| private_key: ${{ env.TEST_KEY_LF }} | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| - name: Test with CRLF formatted key (should auto-normalize) | |
| uses: ./ | |
| with: | |
| playbook: tests/ssh_key_test_playbook.yml | |
| inventory: tests/hosts.yml | |
| private_key: ${{ env.TEST_KEY_CRLF }} | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| - name: Test with key missing trailing newline (should auto-fix) | |
| uses: ./ | |
| with: | |
| playbook: tests/ssh_key_test_playbook.yml | |
| inventory: tests/hosts.yml | |
| private_key: ${{ env.TEST_KEY_NO_NEWLINE }} | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| # kics-scan ignore-block | |
| - name: Test with invalid key format (should fail with validation) | |
| uses: ./ | |
| with: | |
| playbook: tests/ssh_key_test_playbook.yml | |
| inventory: tests/hosts.yml | |
| private_key: "INVALID_TEST_KEY_FORMAT" # Test value, not a real secret | |
| continue-on-error: true | |
| id: test-invalid-key | |
| - name: Verify invalid key was rejected | |
| run: | | |
| if [[ "${{ steps.test-invalid-key.outcome }}" == "success" ]]; then | |
| echo "Expected failure for invalid SSH key but got success" | |
| exit 1 | |
| fi | |
| echo "Invalid key was correctly rejected" | |
| test-error-handling: | |
| name: Error Handling Tests | |
| needs: [setup-environment, test-basic] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup test image | |
| uses: ./.github/actions/setup-test-image | |
| - name: Test with non-existent playbook | |
| uses: ./ | |
| with: | |
| playbook: tests/non_existent.yml | |
| inventory: tests/hosts.yml | |
| continue-on-error: true | |
| id: test-missing-playbook | |
| - name: Test with invalid inventory | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/invalid_hosts.yml | |
| continue-on-error: true | |
| id: test-invalid-inventory | |
| - name: Verify error handling | |
| run: | | |
| if [[ "${{ steps.test-missing-playbook.outcome }}" == "success" ]]; then | |
| echo "Expected failure for missing playbook but got success" | |
| exit 1 | |
| fi | |
| if [[ "${{ steps.test-invalid-inventory.outcome }}" == "success" ]]; then | |
| echo "Expected failure for invalid inventory but got success" | |
| exit 1 | |
| fi | |
| echo "Error handling tests passed" | |
| test-listing: | |
| name: Test Listing Modes | |
| needs: [setup-environment, test-basic] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| strategy: | |
| matrix: | |
| mode: [list_hosts, list_tags, list_tasks] | |
| fail-fast: false | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup test image | |
| uses: ./.github/actions/setup-test-image | |
| - name: Run with ${{ matrix.mode }} | |
| uses: ./ | |
| with: | |
| playbook: tests/tagged_playbook.yml | |
| inventory: tests/hosts.yml | |
| list_hosts: ${{ matrix.mode == 'list_hosts' }} | |
| list_tags: ${{ matrix.mode == 'list_tags' }} | |
| list_tasks: ${{ matrix.mode == 'list_tasks' }} | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| test-execution-options: | |
| name: Test Execution Options | |
| needs: [setup-environment, test-basic] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup test image | |
| uses: ./.github/actions/setup-test-image | |
| - name: Test dry_run mode (check + diff combined) | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| dry_run: "true" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Test flush_cache | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| flush_cache: "true" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Test force_handlers (playbook has a failing task) | |
| uses: ./ | |
| continue-on-error: true | |
| id: test-force-handlers | |
| with: | |
| playbook: tests/handler_failure_playbook.yml | |
| inventory: tests/hosts.yml | |
| force_handlers: "true" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Verify force_handlers was processed | |
| run: | | |
| echo "force_handlers test completed (playbook fails but handlers should run)" | |
| - name: Test custom forks | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| forks: "10" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Test start_at_task | |
| uses: ./ | |
| with: | |
| playbook: tests/start_at_task_playbook.yml | |
| inventory: tests/hosts.yml | |
| start_at_task: "Target task - start here" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| test-multi-input: | |
| name: Test Multiple Inputs | |
| needs: [setup-environment, test-basic] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup test image | |
| uses: ./.github/actions/setup-test-image | |
| - name: Test multiple playbooks (comma-separated) | |
| uses: ./ | |
| with: | |
| playbook: "tests/basic_playbook.yml,tests/second_playbook.yml" | |
| inventory: tests/hosts.yml | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Test multiple playbooks (multiline) | |
| uses: ./ | |
| with: | |
| playbook: | | |
| tests/basic_playbook.yml | |
| tests/second_playbook.yml | |
| inventory: tests/hosts.yml | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Test multiple inventories (comma-separated) | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: "tests/hosts.yml,tests/second_inventory.yml" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Test multiple inventories (multiline) | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: | | |
| tests/hosts.yml | |
| tests/second_inventory.yml | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Test multiline extra_vars | |
| uses: ./ | |
| with: | |
| playbook: tests/extra_vars_playbook.yml | |
| inventory: tests/hosts.yml | |
| extra_vars: | | |
| my_var=multiline_value | |
| env_var=from_multiline | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| test-vault: | |
| name: Test Vault | |
| needs: [setup-environment, test-basic] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup test image | |
| uses: ./.github/actions/setup-test-image | |
| - name: Create vault-encrypted vars file | |
| run: | | |
| pip install ansible-core==2.17.* | |
| echo "vault_secret: decrypted_successfully" > /tmp/vault_vars.yml | |
| ansible-vault encrypt /tmp/vault_vars.yml --vault-password-file <(echo "test_vault_password") | |
| cp /tmp/vault_vars.yml tests/vault_vars.yml | |
| - name: Test with vault_password | |
| uses: ./ | |
| with: | |
| playbook: tests/vault_playbook.yml | |
| inventory: tests/hosts.yml | |
| vault_password: "test_vault_password" | |
| extra_vars: "@tests/vault_vars.yml" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| test-output: | |
| name: Test Output Options | |
| needs: [setup-environment, test-basic] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup test image | |
| uses: ./.github/actions/setup-test-image | |
| - name: Test output_file | |
| uses: ./ | |
| id: test-output-file | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| output_file: ansible_output.txt | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Verify output file was created | |
| run: | | |
| if [[ ! -f ansible_output.txt ]]; then | |
| echo "Output file was not created" | |
| exit 1 | |
| fi | |
| echo "Output file contents:" | |
| cat ansible_output.txt | |
| if [[ ! -s ansible_output.txt ]]; then | |
| echo "Output file is empty" | |
| exit 1 | |
| fi | |
| echo "Output file test passed" | |
| - name: Verify action outputs on success | |
| uses: ./ | |
| id: test-outputs-success | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Check success outputs | |
| run: | | |
| echo "Status: ${{ steps.test-outputs-success.outputs.status }}" | |
| echo "Exit code: ${{ steps.test-outputs-success.outputs.exit_code }}" | |
| if [[ "${{ steps.test-outputs-success.outputs.status }}" != "success" ]]; then | |
| echo "Expected status 'success' but got '${{ steps.test-outputs-success.outputs.status }}'" | |
| exit 1 | |
| fi | |
| if [[ "${{ steps.test-outputs-success.outputs.exit_code }}" != "0" ]]; then | |
| echo "Expected exit_code '0' but got '${{ steps.test-outputs-success.outputs.exit_code }}'" | |
| exit 1 | |
| fi | |
| echo "Output verification passed" | |
| - name: Verify action outputs on failure | |
| uses: ./ | |
| id: test-outputs-failure | |
| continue-on-error: true | |
| with: | |
| playbook: tests/failing_playbook.yml | |
| inventory: tests/hosts.yml | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Check failure outputs | |
| run: | | |
| echo "Status: ${{ steps.test-outputs-failure.outputs.status }}" | |
| echo "Exit code: ${{ steps.test-outputs-failure.outputs.exit_code }}" | |
| if [[ "${{ steps.test-outputs-failure.outputs.status }}" != "failed" ]]; then | |
| echo "Expected status 'failed' but got '${{ steps.test-outputs-failure.outputs.status }}'" | |
| exit 1 | |
| fi | |
| if [[ "${{ steps.test-outputs-failure.outputs.exit_code }}" == "0" ]]; then | |
| echo "Expected non-zero exit_code but got '0'" | |
| exit 1 | |
| fi | |
| echo "Failure output verification passed" | |
| test-lint: | |
| name: Test Lint | |
| needs: [setup-environment, test-basic] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup test image | |
| uses: ./.github/actions/setup-test-image | |
| - name: Test with lint enabled (expect failure - ansible-lint not in image) | |
| uses: ./ | |
| continue-on-error: true | |
| id: test-lint-run | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| lint: "true" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Verify lint flag was processed | |
| run: | | |
| outcome="${{ steps.test-lint-run.outcome }}" | |
| echo "Lint step outcome: $outcome" | |
| if [[ "$outcome" == "success" ]]; then | |
| echo "ansible-lint is available and passed" | |
| elif [[ "$outcome" == "failure" ]]; then | |
| echo "Lint step failed - acceptable if ansible-lint is not installed" | |
| else | |
| echo "Unexpected outcome: $outcome" | |
| exit 1 | |
| fi | |
| test-retries: | |
| name: Test Retries | |
| needs: [setup-environment, test-basic] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup test image | |
| uses: ./.github/actions/setup-test-image | |
| - name: Test retries with failing playbook | |
| uses: ./ | |
| continue-on-error: true | |
| id: test-retries | |
| with: | |
| playbook: tests/failing_playbook.yml | |
| inventory: tests/hosts.yml | |
| retries: "2" | |
| retry_delay: "1" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Verify retries were attempted and action still failed | |
| run: | | |
| if [[ "${{ steps.test-retries.outcome }}" == "success" ]]; then | |
| echo "Expected failure after retries but got success" | |
| exit 1 | |
| fi | |
| echo "Retries test passed - action failed as expected after retries" | |
| - name: Test retries with succeeding playbook | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| retries: "1" | |
| retry_delay: "1" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| test-privilege-escalation: | |
| name: Test Privilege Escalation | |
| needs: [setup-environment, test-basic] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup test image | |
| uses: ./.github/actions/setup-test-image | |
| - name: Test with become flags (syntax check - sudo not in container) | |
| uses: ./ | |
| with: | |
| playbook: tests/become_playbook.yml | |
| inventory: tests/hosts.yml | |
| become: "true" | |
| become_method: "sudo" | |
| become_user: "root" | |
| syntax_check: "true" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| test-galaxy-options: | |
| name: Test Galaxy Options | |
| needs: [setup-environment, test-basic] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup test image | |
| uses: ./.github/actions/setup-test-image | |
| - name: Test galaxy_force (reinstall) | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| galaxy_file: tests/requirements.yml | |
| galaxy_force: "true" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Test galaxy_no_deps | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| galaxy_file: tests/requirements.yml | |
| galaxy_no_deps: "true" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Test galaxy_timeout | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| galaxy_file: tests/requirements.yml | |
| galaxy_timeout: "120" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Test galaxy_force_with_deps | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| galaxy_file: tests/requirements.yml | |
| galaxy_force_with_deps: "true" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Test galaxy_ignore_certs | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| galaxy_file: tests/requirements.yml | |
| galaxy_ignore_certs: "true" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| test-connection: | |
| name: Test Connection Options | |
| needs: [setup-environment, test-basic] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Setup test image | |
| uses: ./.github/actions/setup-test-image | |
| - name: Test with explicit connection type | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| connection: "local" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Fetch GitHub known_hosts | |
| id: known-hosts | |
| run: | | |
| { | |
| echo "value<<KNOWN_HOSTS_EOF" | |
| ssh-keyscan github.com 2>/dev/null | |
| echo "KNOWN_HOSTS_EOF" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Test with known_hosts | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| connection: "local" | |
| known_hosts: ${{ steps.known-hosts.outputs.value }} | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| - name: Test with timeout | |
| uses: ./ | |
| with: | |
| playbook: tests/basic_playbook.yml | |
| inventory: tests/hosts.yml | |
| connection: "local" | |
| timeout: "60" | |
| env: | |
| ANSIBLE_HOST_KEY_CHECKING: "false" | |
| ANSIBLE_DEPRECATION_WARNINGS: "false" | |
| test-summary: | |
| name: Test Summary | |
| needs: | |
| - ci | |
| - lint | |
| - security-secrets | |
| - setup-environment | |
| - build-action | |
| - test-basic | |
| - test-advanced | |
| - test-modes | |
| - test-parameters | |
| - test-ssh-key-handling | |
| - test-error-handling | |
| - test-listing | |
| - test-execution-options | |
| - test-multi-input | |
| - test-vault | |
| - test-output | |
| - test-lint | |
| - test-retries | |
| - test-privilege-escalation | |
| - test-galaxy-options | |
| - test-connection | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pull-requests: write | |
| contents: read | |
| if: always() | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: Generate comprehensive test summary | |
| run: | | |
| ./tests/test-summary.sh "Action-Tests" \ | |
| "Go CI=${{ needs.ci.result }}" \ | |
| "Lint=${{ needs.lint.result }}" \ | |
| "Secret Scan=${{ needs.security-secrets.result }}" \ | |
| "Basic Tests=${{ needs.test-basic.result }}" \ | |
| "Advanced Tests=${{ needs.test-advanced.result }}" \ | |
| "Mode Tests=${{ needs.test-modes.result }}" \ | |
| "Parameter Tests=${{ needs.test-parameters.result }}" \ | |
| "SSH Key Handling Tests=${{ needs.test-ssh-key-handling.result }}" \ | |
| "Error Handling Tests=${{ needs.test-error-handling.result }}" \ | |
| "Listing Mode Tests=${{ needs.test-listing.result }}" \ | |
| "Execution Options Tests=${{ needs.test-execution-options.result }}" \ | |
| "Multi-Input Tests=${{ needs.test-multi-input.result }}" \ | |
| "Vault Tests=${{ needs.test-vault.result }}" \ | |
| "Output Tests=${{ needs.test-output.result }}" \ | |
| "Lint Tests=${{ needs.test-lint.result }}" \ | |
| "Retry Tests=${{ needs.test-retries.result }}" \ | |
| "Privilege Escalation Tests=${{ needs.test-privilege-escalation.result }}" \ | |
| "Galaxy Options Tests=${{ needs.test-galaxy-options.result }}" \ | |
| "Connection Tests=${{ needs.test-connection.result }}" | |
| - name: Upload test artifacts | |
| if: always() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: action-test-results-${{ github.run_id }} | |
| path: | | |
| ./Action-Tests-results.md | |
| ./**/test-*.log | |
| retention-days: 30 | |
| - name: Comment on pull request with test results | |
| if: github.event_name == 'pull_request' | |
| uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3 | |
| with: | |
| file-path: ./Action-Tests-results.md | |
| comment-tag: action-test-results | |
| mode: upsert | |
| - name: Test quality gate | |
| if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') | |
| run: | | |
| echo "One or more required jobs failed or were cancelled; see the summary above." | |
| exit 1 |