fix: add ReadHeaderTimeout to http servers (G112) #3780
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 | |
| on: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| pull_request: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.run_id }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| changes: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| outputs: | |
| go: ${{ steps.filter.outputs.go }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4 | |
| id: filter | |
| with: | |
| filters: | | |
| go: | |
| - '**/*.go' | |
| - 'go.mod' | |
| - 'go.sum' | |
| - '.goreleaser.yml' | |
| - 'e2e/**' | |
| - '.github/workflows/pr-ci.yml' | |
| - 'hack/licenses/**' | |
| - 'THIRD_PARTY_LICENSES.md' | |
| precommit: | |
| name: Pre-commit | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: j178/prek-action@4e14d07f9231acabce116ccfca13b13dd9755ece # v3.0.0 | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: setup Go | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 | |
| with: | |
| go-version-file: go.mod | |
| - name: golangci-lint | |
| uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9 | |
| with: | |
| version: v2.12.2 | |
| only-new-issues: true | |
| can-read-secret: | |
| name: Can Read Secret | |
| runs-on: ubuntu-latest | |
| outputs: | |
| secret-set: ${{ steps.check-secret.outputs.secret-set }} | |
| steps: | |
| - name: Check secret | |
| id: check-secret | |
| run: | | |
| if [ -z "${{ secrets.DEVSY_GITHUB_APP_ID }}" ]; then | |
| echo "secret-set=false" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "secret-set=true" >> "$GITHUB_OUTPUT" | |
| fi | |
| build-cli: | |
| name: Build CLI Binary on ${{ matrix.runner }} | |
| needs: [changes, precommit, lint] | |
| if: needs.changes.outputs.go == 'true' | |
| strategy: | |
| matrix: | |
| include: | |
| - runner: ubuntu-latest | |
| - runner: macos-latest | |
| - runner: windows-latest | |
| runs-on: ${{ matrix.runner }} | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 | |
| with: | |
| go-version-file: go.mod | |
| - name: get operating system lowercase | |
| id: os | |
| shell: bash | |
| run: | | |
| OS=$(echo "${{ runner.os }}" | tr '[:upper:]' '[:lower:]') | |
| if [ "$OS" == "macos" ]; then | |
| OS="darwin" | |
| fi | |
| echo "runner_os=$OS" >> "$GITHUB_OUTPUT" | |
| - uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7 | |
| with: | |
| distribution: goreleaser | |
| version: "~> v2" | |
| args: build --id devsy-${{ steps.os.outputs.runner_os }} --snapshot | |
| env: | |
| DEVSY_CLI_VERSION: v0.0.0 | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: devsy-${{ steps.os.outputs.runner_os }} | |
| path: dist/devsy-${{ steps.os.outputs.runner_os }}_*/devsy-${{ steps.os.outputs.runner_os }}-* | |
| - name: build e2e test binary | |
| if: matrix.runner == 'ubuntu-latest' || matrix.runner == 'windows-latest' | |
| shell: bash | |
| working-directory: ./e2e | |
| env: | |
| CGO_ENABLED: 0 | |
| run: | | |
| OUT="e2e.test" | |
| if [ "${{ runner.os }}" == "Windows" ]; then | |
| OUT="e2e.test.exe" | |
| fi | |
| go test -c -o "$OUT" ./ | |
| - name: upload e2e test binary | |
| if: matrix.runner == 'ubuntu-latest' || matrix.runner == 'windows-latest' | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 | |
| with: | |
| name: e2e-test-${{ steps.os.outputs.runner_os }} | |
| path: ./e2e/e2e.test* | |
| licenses: | |
| name: Third-party licenses | |
| needs: [changes, precommit, lint] | |
| if: needs.changes.outputs.go == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 | |
| with: | |
| go-version-file: go.mod | |
| - name: Check license policy and attribution | |
| run: go run ./hack/licenses --check | |
| integration-tests-unprivileged: | |
| name: Test ${{ matrix.label }} on ${{ matrix.runner }} | |
| needs: [changes, build-cli] | |
| if: needs.changes.outputs.go == 'true' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - label: context | |
| runner: ubuntu-latest | |
| - label: extends | |
| runner: ubuntu-latest | |
| - label: outdated | |
| runner: ubuntu-latest | |
| - label: machine | |
| runner: ubuntu-latest | |
| - label: self-update | |
| runner: ubuntu-latest | |
| - label: upgrade | |
| runner: ubuntu-latest | |
| runs-on: ${{ matrix.runner }} | |
| timeout-minutes: 45 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| - name: get operating system lowercase | |
| id: os | |
| shell: bash | |
| run: | | |
| OS=$(echo "${{ runner.os }}" | tr '[:upper:]' '[:lower:]') | |
| echo "runner_os=$OS" >> "$GITHUB_OUTPUT" | |
| - name: download CLI artifacts | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| pattern: devsy-${{ steps.os.outputs.runner_os }} | |
| path: ${{ runner.temp }}/devsy-bin/ | |
| merge-multiple: true | |
| - name: download e2e test binary | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: e2e-test-${{ steps.os.outputs.runner_os }} | |
| path: ./e2e/ | |
| - name: setup executable | |
| shell: bash | |
| working-directory: ./e2e | |
| run: | | |
| TEMP_DIR="${{ runner.temp }}" | |
| ls -R "$TEMP_DIR/devsy-bin/" | |
| mkdir -p ./bin/ | |
| find "$TEMP_DIR/devsy-bin/" -type f -name "devsy-*" -exec cp {} ./bin \; | |
| find ./bin -name "devsy-*" -exec chmod +x {} \; | |
| chmod +x ./e2e.test | |
| ls -R ./bin/ | |
| - name: run test | |
| shell: bash | |
| working-directory: ./e2e | |
| env: | |
| GH_USERNAME: ${{ github.repository_owner }} | |
| GH_ACCESS_TOKEN: ${{ github.token }} | |
| GH_CREDENTIAL_USERNAME: x-access-token | |
| run: | | |
| ./e2e.test -test.v -ginkgo.v -test.timeout 1500s -ginkgo.fail-on-empty --ginkgo.label-filter="${{ matrix.label }}" | |
| integration-tests: | |
| name: Test ${{ matrix.label }}${{ matrix.install-podman && format(' ({0})', matrix.install-podman) || '' }} on ${{ matrix.runner }} | |
| needs: [changes, can-read-secret, build-cli] | |
| if: needs.changes.outputs.go == 'true' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - label: ide | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: machine-provider | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: integration | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: tunnel | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| flake-attempts: 2 | |
| - label: mcp | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: provider | |
| runner: ubuntu-latest | |
| free-disk-space: true | |
| install-kind: true | |
| requires-secret: false | |
| flake-attempts: 2 | |
| - label: ssh | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: ssh-agent-forward | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: ssh-ports-attributes | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: ssh-tunnel-mode | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: ssh-credentials-server-race | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: build | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: true | |
| requires-secret: true | |
| - label: docker-install | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: exec | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: ci | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: feature | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: extends-up | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: down | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: rename | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: delivery | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: logs | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: templates | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: config-apply | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: run-user-commands | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: config-read | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| # Up tests | |
| - label: up-workspaces | |
| runner: ubuntu-latest | |
| free-disk-space: true | |
| install-kind: true | |
| requires-secret: false | |
| - label: up-behaviors | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| - label: up-handle-errors | |
| runner: ubuntu-latest | |
| free-disk-space: true | |
| install-kind: true | |
| requires-secret: false | |
| - label: up-private-token | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: true | |
| - label: up-provider-kubernetes | |
| runner: ubuntu-latest | |
| free-disk-space: true | |
| install-kind: true | |
| requires-secret: false | |
| - label: up-provider-podman-rootless-basic | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| install-podman: rootless | |
| test-timeout: 600s | |
| job-timeout-minutes: 20 | |
| flake-attempts: 2 | |
| - label: up-provider-podman-rootless-exec | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| install-podman: rootless | |
| test-timeout: 600s | |
| job-timeout-minutes: 20 | |
| flake-attempts: 2 | |
| - label: up-provider-podman-rootless-lifecycle | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| install-podman: rootless | |
| test-timeout: 600s | |
| job-timeout-minutes: 20 | |
| flake-attempts: 2 | |
| - label: up-provider-podman-rootless-config | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| install-podman: rootless | |
| test-timeout: 600s | |
| job-timeout-minutes: 20 | |
| flake-attempts: 2 | |
| - label: up-provider-podman-rootless-features | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| install-podman: rootless | |
| test-timeout: 600s | |
| job-timeout-minutes: 20 | |
| flake-attempts: 2 | |
| - label: up-provider-podman-rootful-basic | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| install-podman: rootful | |
| test-timeout: 600s | |
| job-timeout-minutes: 20 | |
| flake-attempts: 2 | |
| - label: up-provider-podman-rootful-lifecycle | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| install-podman: rootful | |
| test-timeout: 600s | |
| job-timeout-minutes: 20 | |
| flake-attempts: 2 | |
| - label: up-provider-podman-rootful-lifecycle-2 | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| install-podman: rootful | |
| test-timeout: 600s | |
| job-timeout-minutes: 20 | |
| flake-attempts: 2 | |
| - label: up-provider-podman-rootful-config | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| install-podman: rootful | |
| test-timeout: 600s | |
| job-timeout-minutes: 20 | |
| flake-attempts: 2 | |
| - label: up-provider-podman-rootful-features | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| install-podman: rootful | |
| test-timeout: 600s | |
| job-timeout-minutes: 20 | |
| flake-attempts: 2 | |
| - label: up-provider-docker | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: true | |
| requires-secret: false | |
| - label: up-provider-microsandbox | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| install-microsandbox: true | |
| # Snapshot tests | |
| - label: snapshot | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| configure-insecure-registry: true | |
| # Up Docker Compose tests | |
| - label: up-docker-compose | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: false | |
| requires-secret: false | |
| # Up Docker Feature tests | |
| - label: up-features | |
| runner: ubuntu-latest | |
| free-disk-space: false | |
| install-kind: true | |
| requires-secret: false | |
| # Windows tests | |
| - label: provider | |
| runner: windows-latest | |
| free-disk-space: false | |
| install-kind: true | |
| requires-secret: false | |
| - label: up-docker-wsl | |
| runner: windows-latest | |
| free-disk-space: false | |
| install-kind: true | |
| requires-secret: false | |
| - label: up-features | |
| runner: windows-latest | |
| free-disk-space: false | |
| install-kind: true | |
| requires-secret: false | |
| runs-on: ${{ matrix.runner }} | |
| timeout-minutes: ${{ matrix.job-timeout-minutes || 45 }} | |
| steps: | |
| - uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 | |
| background: true | |
| if: matrix.free-disk-space == true && runner.os == 'Linux' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true') | |
| with: | |
| docker-images: false | |
| swap-storage: false | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| if: matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true' | |
| - name: install gnupg2 | |
| if: runner.os == 'Linux' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true') | |
| run: sudo apt-get install -y gnupg2 | |
| - name: get operating system lowercase | |
| if: matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true' | |
| id: os | |
| shell: bash | |
| run: | | |
| OS=$(echo "${{ runner.os }}" | tr '[:upper:]' '[:lower:]') | |
| if [ "$OS" == "macos" ]; then | |
| OS="darwin" | |
| fi | |
| echo "runner_os=$OS" >> "$GITHUB_OUTPUT" | |
| - name: download CLI artifacts | |
| if: matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true' | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| pattern: devsy-${{ steps.os.outputs.runner_os }} | |
| path: ${{ runner.temp }}/devsy-bin/ | |
| merge-multiple: true | |
| - name: download Linux CLI artifacts for Windows | |
| if: runner.os == 'Windows' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true') | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| pattern: devsy-linux | |
| path: ${{ runner.temp }}/devsy-bin/ | |
| merge-multiple: true | |
| - name: download e2e test binary | |
| if: matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true' | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 | |
| with: | |
| name: e2e-test-${{ steps.os.outputs.runner_os }} | |
| path: ./e2e/ | |
| - name: setup executable | |
| if: matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true' | |
| shell: bash | |
| working-directory: ./e2e | |
| run: | | |
| TEMP_DIR="${{ runner.temp }}" | |
| if [ "${{ runner.os }}" == "Windows" ]; then | |
| TEMP_DIR="${TEMP_DIR//\\//}" | |
| fi | |
| ls -R "$TEMP_DIR/devsy-bin/" | |
| mkdir -p ./bin/ | |
| find "$TEMP_DIR/devsy-bin/" -type f -name "devsy-*" -exec cp {} ./bin \; | |
| find ./bin -name "devsy-*" -exec chmod +x {} \; | |
| if [ "${{ runner.os }}" == "Linux" ]; then | |
| chmod +x ./e2e.test | |
| fi | |
| ls -R ./bin/ | |
| - name: generate uuid | |
| if: matrix.install-kind == true && runner.os != 'Windows' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true') | |
| id: uuid | |
| shell: bash | |
| run: | | |
| UUID=$(python -c "import uuid; print(uuid.uuid4().hex)") | |
| echo "result=$UUID" >> "$GITHUB_OUTPUT" | |
| - name: cache podman installer (Windows) | |
| if: matrix.install-kind == true && runner.os == 'Windows' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true') | |
| id: podman-cache-windows | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ${{ runner.temp }}/podman.msi | |
| key: ${{ runner.os }}-${{ runner.arch }}-podman-v5.8.2 | |
| - name: install and start podman (Windows) | |
| if: matrix.install-kind == true && runner.os == 'Windows' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true') | |
| shell: pwsh | |
| run: | | |
| $msiPath = "$env:RUNNER_TEMP\podman.msi" | |
| if ("${{ steps.podman-cache-windows.outputs.cache-hit }}" -ne "true") { | |
| $msiUrl = "https://github.com/containers/podman/releases/download/v5.8.2/podman-installer-windows-amd64.msi" | |
| Invoke-WebRequest -Uri $msiUrl -OutFile $msiPath | |
| } | |
| $expectedHash = "eda54f26f9695d198d9a679fa45ae24ba35b78444f432b5fe0c122c5a3624c57" | |
| $actualHash = (Get-FileHash -Path $msiPath -Algorithm SHA256).Hash.ToLower() | |
| if ($actualHash -ne $expectedHash) { | |
| throw "SHA256 mismatch for podman MSI! Expected: $expectedHash, Got: $actualHash" | |
| } | |
| Write-Host "Podman MSI checksum verified: $actualHash" | |
| $installDir = "C:\Program Files\RedHat\Podman" | |
| $logFile = "$env:RUNNER_TEMP\podman-install.log" | |
| $proc = Start-Process msiexec.exe -Wait -PassThru -ArgumentList "/i `"$msiPath`" /qn /norestart /l*v `"$logFile`" INSTALLDIR=`"$installDir`"" | |
| Write-Host "MSI exit code: $($proc.ExitCode)" | |
| if (!(Test-Path "$installDir\podman.exe")) { | |
| Write-Host "--- MSI install log (last 50 lines) ---" | |
| Get-Content $logFile -Tail 50 | |
| Write-Host "--- Searching for podman.exe ---" | |
| Get-ChildItem "C:\" -Filter "podman.exe" -Recurse -Depth 4 -ErrorAction SilentlyContinue | ForEach-Object { Write-Host $_.FullName } | |
| throw "podman.exe not found at $installDir" | |
| } | |
| echo "$installDir" | Out-File -Append -FilePath $env:GITHUB_PATH -Encoding utf8 | |
| wsl --set-default-version 2 | |
| & "$installDir\podman.exe" machine init | |
| & "$installDir\podman.exe" machine set --rootful | |
| & "$installDir\podman.exe" machine start | |
| - name: cache kind.exe (Windows) | |
| if: matrix.install-kind == true && runner.os == 'Windows' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true') | |
| id: kind-cache-windows | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ${{ runner.temp }}/kind.exe | |
| key: ${{ runner.os }}-${{ runner.arch }}-kind-v0.24.0 | |
| - name: setup kind (Windows) | |
| if: matrix.install-kind == true && runner.os == 'Windows' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true') | |
| shell: bash | |
| env: | |
| KIND_EXPERIMENTAL_PROVIDER: podman | |
| DOCKER_HOST: npipe:////./pipe/podman-machine-default | |
| run: | | |
| if [ "${{ steps.kind-cache-windows.outputs.cache-hit }}" != "true" ]; then | |
| curl -Lo "$RUNNER_TEMP/kind.exe" "https://github.com/kubernetes-sigs/kind/releases/download/v0.24.0/kind-windows-amd64" | |
| expected="6f724188289cc79395f45afae0f2b85e0d220c2b84c6ed2f5047d9d0c9a67028" | |
| actual=$(sha256sum "$RUNNER_TEMP/kind.exe" | awk '{print $1}' | sed 's/^[^a-f0-9]*//') | |
| if [ "$actual" != "$expected" ]; then | |
| echo "SHA256 mismatch for kind.exe! Expected: $expected, Got: $actual" | |
| exit 1 | |
| fi | |
| echo "kind.exe checksum verified: $actual" | |
| fi | |
| export PATH="$RUNNER_TEMP:$PATH" | |
| echo "$RUNNER_TEMP" >> "$GITHUB_PATH" | |
| CLUSTER_NAME=$(python -c "import uuid; print(uuid.uuid4().hex)") | |
| kind create cluster --name "$CLUSTER_NAME" --image kindest/node:v1.34.0@sha256:7416a61b42b1662ca6ca89f02028ac133a309a2a30ba309614e8ec94d976dc5a | |
| # NOTE: skevetter/setup-kind does not work on Windows runners | |
| - name: setup kind | |
| if: matrix.install-kind == true && runner.os != 'Windows' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true') | |
| uses: skevetter/setup-kind@7febac2ed35df332069b3bb687c6b1fa00fc0883 # v1 | |
| with: | |
| name: ${{ steps.uuid.outputs.result }} | |
| version: v0.24.0 | |
| image: kindest/node:v1.34.0@sha256:7416a61b42b1662ca6ca89f02028ac133a309a2a30ba309614e8ec94d976dc5a | |
| skipClusterLogsExport: true | |
| - name: cache podman installer (Linux) | |
| if: (matrix.install-podman == 'rootless' || matrix.install-podman == 'rootful') && runner.os == 'Linux' | |
| id: podman-cache-linux | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: ${{ runner.temp }}/podman-linux-amd64.tar.gz | |
| key: ${{ runner.os }}-${{ runner.arch }}-podman-static-v5.8.2 | |
| - name: install podman (Linux) | |
| if: (matrix.install-podman == 'rootless' || matrix.install-podman == 'rootful') && runner.os == 'Linux' | |
| timeout-minutes: 5 | |
| run: | | |
| archive="${{ runner.temp }}/podman-linux-amd64.tar.gz" | |
| if [ "${{ steps.podman-cache-linux.outputs.cache-hit }}" != "true" ]; then | |
| curl -fsSL -o "$archive" \ | |
| https://github.com/mgoltzsche/podman-static/releases/download/v5.8.2/podman-linux-amd64.tar.gz | |
| fi | |
| expectedHash="228b9adf1ba3585d1d72f0a4bb9a669de5ea806d13884b2c43b5e65601a1a580" | |
| actualHash=$(sha256sum "$archive" | cut -d' ' -f1) | |
| if [ "$actualHash" != "$expectedHash" ]; then | |
| echo "::error::SHA256 mismatch for podman-static archive! Expected: $expectedHash, Got: $actualHash" | |
| exit 1 | |
| fi | |
| tar -xzf "$archive" -C "${{ runner.temp }}" | |
| sudo cp -r "${{ runner.temp }}/podman-linux-amd64/usr" "${{ runner.temp }}/podman-linux-amd64/etc" / | |
| command -v newuidmap >/dev/null || sudo apt-get install -y uidmap | |
| - name: Install Podman (Linux rootless) | |
| if: matrix.install-podman == 'rootless' && runner.os == 'Linux' | |
| run: | | |
| podman info | |
| podman run --rm busybox@sha256:fd8d9aa63ba2f0982b5304e1ee8d3b90a210bc1ffb5314d980eb6962f1a9715d echo "podman runtime preflight OK" | |
| - name: Install Podman (Linux rootful) | |
| if: matrix.install-podman == 'rootful' && runner.os == 'Linux' | |
| run: | | |
| sudo systemctl daemon-reload | |
| sudo systemctl enable --now podman.socket | |
| if ! timeout 30 bash -c 'until sudo podman --remote --url unix:///run/podman/podman.sock info >/dev/null 2>&1; do sleep 1; done'; then | |
| echo "::error::podman service did not become ready within 30s" | |
| sudo systemctl status podman.socket --no-pager || true | |
| sudo journalctl -u podman.socket --no-pager -n 100 || true | |
| exit 1 | |
| fi | |
| echo "DOCKER_HOST=unix:///run/podman/podman.sock" >> "$GITHUB_ENV" | |
| sudo podman --remote --url unix:///run/podman/podman.sock info | |
| sudo podman run --rm busybox@sha256:fd8d9aa63ba2f0982b5304e1ee8d3b90a210bc1ffb5314d980eb6962f1a9715d echo "podman runtime preflight OK" | |
| - name: get microsandbox latest version | |
| if: matrix.install-microsandbox == true && runner.os == 'Linux' | |
| id: msb-version | |
| run: | | |
| version=$(curl -fsSL https://api.github.com/repos/superradcompany/microsandbox/releases/latest | grep '"tag_name"' | head -1 | sed 's/.*"tag_name":[[:space:]]*"\([^"]*\)".*/\1/') | |
| echo "version=$version" >> "$GITHUB_OUTPUT" | |
| - name: cache microsandbox (Linux) | |
| if: matrix.install-microsandbox == true && runner.os == 'Linux' | |
| id: msb-cache | |
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | |
| with: | |
| path: | | |
| ~/.microsandbox | |
| ~/.local/bin/msb | |
| ~/.local/bin/microsandbox | |
| key: ${{ runner.os }}-${{ runner.arch }}-microsandbox-${{ steps.msb-version.outputs.version }} | |
| - name: Install microsandbox (Linux) | |
| if: matrix.install-microsandbox == true && runner.os == 'Linux' && steps.msb-cache.outputs.cache-hit != 'true' | |
| run: | | |
| curl -fsSL https://install.microsandbox.dev | sh | |
| - name: configure microsandbox (Linux) | |
| if: matrix.install-microsandbox == true && runner.os == 'Linux' | |
| run: | | |
| echo "$HOME/.local/bin" >> "$GITHUB_PATH" | |
| # The e2e test skips gracefully if KVM is unavailable on the runner. | |
| "$HOME/.local/bin/msb" doctor || true | |
| - name: remove docker | |
| if: matrix.label == 'docker-install' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true') | |
| run: | | |
| sudo systemctl stop docker.socket docker.service | |
| sudo apt-get remove -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin | |
| sudo rm -rf /var/lib/docker /var/lib/containerd /usr/bin/docker /usr/bin/dockerd | |
| - name: configure insecure registry for snapshot tests (Linux) | |
| if: matrix.configure-insecure-registry == true && runner.os == 'Linux' | |
| run: | | |
| echo "127.0.0.1 host.docker.internal" | sudo tee -a /etc/hosts | |
| sudo mkdir -p /etc/docker | |
| existing="$(sudo cat /etc/docker/daemon.json 2>/dev/null || echo '{}')" | |
| echo "$existing" | jq '.["insecure-registries"] = ((.["insecure-registries"] // []) + ["host.docker.internal:15500"] | unique)' \ | |
| | sudo tee /etc/docker/daemon.json > /dev/null | |
| sudo systemctl restart docker | |
| timeout 30 bash -c 'until docker info >/dev/null 2>&1; do sleep 1; done' | |
| - name: generate GitHub App token | |
| if: matrix.requires-secret == true && needs.can-read-secret.outputs.secret-set == 'true' | |
| id: app-token | |
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3 | |
| with: | |
| client-id: ${{ secrets.DEVSY_GITHUB_APP_ID }} | |
| private-key: ${{ secrets.DEVSY_GITHUB_APP_PRIVATE_KEY }} | |
| owner: ${{ github.repository_owner }} | |
| - name: run test | |
| if: matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true' | |
| shell: bash | |
| working-directory: ./e2e | |
| env: | |
| # NOTE: GitHub credentials are required for tests using private repos | |
| GH_USERNAME: ${{ github.repository_owner }} | |
| GH_ACCESS_TOKEN: ${{ steps.app-token.outputs.token || github.token }} | |
| GH_CREDENTIAL_USERNAME: x-access-token | |
| TEST_TIMEOUT: ${{ matrix.test-timeout || '1500s' }} | |
| FLAKE_ATTEMPTS: ${{ matrix.flake-attempts || '1' }} | |
| run: | | |
| if [ "${{ runner.os }}" == "Linux" ]; then | |
| sudo \ | |
| GH_USERNAME="${GH_USERNAME}" \ | |
| GH_ACCESS_TOKEN="${GH_ACCESS_TOKEN}" \ | |
| GH_CREDENTIAL_USERNAME="${GH_CREDENTIAL_USERNAME}" \ | |
| KUBECONFIG="${KUBECONFIG:-$HOME/.kube/config}" \ | |
| ${DOCKER_HOST:+DOCKER_HOST="${DOCKER_HOST}"} \ | |
| PATH="${PATH}" \ | |
| ./e2e.test -test.v -ginkgo.v -test.timeout "${TEST_TIMEOUT}" -ginkgo.fail-on-empty -ginkgo.flake-attempts="${FLAKE_ATTEMPTS}" --ginkgo.label-filter="${{ matrix.label }}" | |
| else | |
| GH_USERNAME="${GH_USERNAME}" \ | |
| GH_ACCESS_TOKEN="${GH_ACCESS_TOKEN}" \ | |
| GH_CREDENTIAL_USERNAME="${GH_CREDENTIAL_USERNAME}" \ | |
| KUBECONFIG="${KUBECONFIG:-$HOME/.kube/config}" \ | |
| PATH="${PATH}" \ | |
| DOCKER_HOST="npipe:////./pipe/podman-machine-default" \ | |
| ./e2e.test.exe -test.v -ginkgo.v -test.timeout "${TEST_TIMEOUT}" -ginkgo.fail-on-empty -ginkgo.flake-attempts="${FLAKE_ATTEMPTS}" --ginkgo.label-filter="${{ matrix.label }}" | |
| fi | |
| - name: verify docker is installed | |
| if: matrix.label == 'docker-install' && (matrix.requires-secret == false || needs.can-read-secret.outputs.secret-set == 'true') | |
| run: docker --version && docker ps | |
| ci-success: | |
| name: CI Success | |
| runs-on: ubuntu-latest | |
| if: always() | |
| needs: | |
| - changes | |
| - precommit | |
| - lint | |
| - licenses | |
| - build-cli | |
| - integration-tests-unprivileged | |
| - integration-tests | |
| steps: | |
| - name: Check required jobs | |
| run: | | |
| # Fail if any required job failed (not skipped) | |
| if [[ "${{ needs.changes.result }}" == "failure" ]] || \ | |
| [[ "${{ needs.precommit.result }}" == "failure" ]] || \ | |
| [[ "${{ needs.lint.result }}" == "failure" ]] || \ | |
| [[ "${{ needs.licenses.result }}" == "failure" ]] || \ | |
| [[ "${{ needs.build-cli.result }}" == "failure" ]] || \ | |
| [[ "${{ needs.integration-tests-unprivileged.result }}" == "failure" ]] || \ | |
| [[ "${{ needs.integration-tests.result }}" == "failure" ]]; then | |
| echo "One or more required jobs failed" | |
| exit 1 | |
| fi | |
| echo "All required jobs passed or were skipped" |