From 4c5c98e8c6ad8c587662c5e0cac97bbea2176af8 Mon Sep 17 00:00:00 2001 From: Lucian Petrut Date: Wed, 11 Dec 2024 13:18:48 +0200 Subject: [PATCH] Deduplicate github actions We have multiple github actions that run e2e tests and share a significant amount of logic. We'll add reusable actions, making the workflows much easier to maintain. --- .github/actions/download-k8s-snap/action.yaml | 61 ++++++ .github/actions/install-lxd/action.yaml | 20 ++ .github/workflows/build-snap.yaml | 51 +++++ .github/workflows/cron-jobs.yaml | 53 +---- .github/workflows/e2e-tests.yaml | 72 +++++++ .github/workflows/go.yaml | 16 +- .github/workflows/integration-informing.yaml | 104 ---------- .github/workflows/integration.yaml | 187 ------------------ .github/workflows/lint_and_integration.yaml | 139 +++++++++++++ .github/workflows/nightly-test.yaml | 65 ++---- .github/workflows/python.yaml | 37 ---- .github/workflows/security-scan.yaml | 80 ++++++++ 12 files changed, 444 insertions(+), 441 deletions(-) create mode 100644 .github/actions/download-k8s-snap/action.yaml create mode 100644 .github/actions/install-lxd/action.yaml create mode 100644 .github/workflows/build-snap.yaml create mode 100644 .github/workflows/e2e-tests.yaml delete mode 100644 .github/workflows/integration-informing.yaml delete mode 100644 .github/workflows/integration.yaml create mode 100644 .github/workflows/lint_and_integration.yaml delete mode 100644 .github/workflows/python.yaml create mode 100644 .github/workflows/security-scan.yaml diff --git a/.github/actions/download-k8s-snap/action.yaml b/.github/actions/download-k8s-snap/action.yaml new file mode 100644 index 000000000..d655459a3 --- /dev/null +++ b/.github/actions/download-k8s-snap/action.yaml @@ -0,0 +1,61 @@ +name: Download k8s-snap + +inputs: + # Download k8s-snap using either a GH action artifact or a snap channel. + artifact: + description: The name of a GH action artifact. + type: string + channel: + description: k8s snap channel. + type: string + +outputs: + snap-path: + description: The *.snap destination path. + value: ${{ steps.retrieve-path.outputs.snap-path }} + +runs: + using: "composite" + steps: + - name: Exit if no input provided + if: inputs.artifact == '' && inputs.channel == '' + shell: bash + run: | + echo "No k8s-snap artifact or channel specified..." + exit 1 + - name: Exit if multiple inputs provided + if: inputs.artifact != '' && inputs.channel != '' + shell: bash + run: | + echo "Received snap artifact AND snap channel." + exit 1 + + - name: Download snap artifact + if: inputs.artifact != '' + uses: actions/download-artifact@v4 + with: + name: ${{ inputs.artifact }} + path: ${{ github.workspace }} + + - name: Download snap channel + if: inputs.channel != '' + shell: bash + run: | + snap download k8s --channel=${{ inputs.channel }} --basename k8s + full_path=`realpath k8s.snap` + echo "Downloaded snap: $full_path" + ls -lh $full_path + + - name: Retrieve resulting snap path + shell: bash + id: retrieve-path + run: | + if [[ -n "${{ inputs.artifact }}" ]]; then + snap_path="${{ github.workspace }}/${{ inputs.artifact }}" + else + snap_path="${{ github.workspace }}/k8s.snap" + fi + echo "snap-path=$snap_path" >> "$GITHUB_OUTPUT" + + echo "Downloaded snap: $snap_path" + ls -lh $snap_path diff --git a/.github/actions/install-lxd/action.yaml b/.github/actions/install-lxd/action.yaml new file mode 100644 index 000000000..71b2475d1 --- /dev/null +++ b/.github/actions/install-lxd/action.yaml @@ -0,0 +1,20 @@ +name: Install lxd + +runs: + using: "composite" + steps: + - name: Install lxd snap + shell: bash + run: | + sudo snap refresh lxd --channel 5.21/stable + - name: Initialize lxd + shell: bash + run: | + sudo lxd init --auto + sudo usermod --append --groups lxd $USER + sg lxd -c 'lxc version' + - name: Apply Docker iptables workaround + shell: bash + run: | + sudo iptables -I DOCKER-USER -i lxdbr0 -j ACCEPT + sudo iptables -I DOCKER-USER -o lxdbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT diff --git a/.github/workflows/build-snap.yaml b/.github/workflows/build-snap.yaml new file mode 100644 index 000000000..bd9e6f768 --- /dev/null +++ b/.github/workflows/build-snap.yaml @@ -0,0 +1,51 @@ +name: Build k8s-snap + +on: + workflow_call: + inputs: + flavor: + description: k8s-snap flavor (e.g. moonray or strict) + type: string + outputs: + snap-artifact: + description: Name of the uploaded snap artifact + value: ${{ jobs.build-snap.outputs.snap-artifact }} + +jobs: + build-snap: + name: Build snap + runs-on: ubuntu-20.04 + outputs: + snap-artifact: ${{ steps.build.outputs.snap-artifact }} + steps: + - name: Checking out repo + uses: actions/checkout@v4 + - name: Apply patches + if: inputs.flavor != '' + run: | + ./build-scripts/patches/${{ inputs.flavor }}/apply + - name: Install lxd + uses: ./.github/actions/install-lxd + - name: Install snapcraft + run: | + sudo snap install snapcraft --classic + - name: Build snap + id: build + env: + flavor: ${{ inputs.flavor }} + run: | + if [[ -n "$flavor" ]]; then + out_snap=k8s-$flavor.snap + else + out_snap=k8s.snap + fi + + sg lxd -c 'snapcraft --use-lxd' + mv k8s_*.snap $out_snap + + echo "snap-artifact=$out_snap" >> "$GITHUB_OUTPUT" + - name: Uploading snap + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.build.outputs.snap-artifact }} + path: ${{ steps.build.outputs.snap-artifact }} diff --git a/.github/workflows/cron-jobs.yaml b/.github/workflows/cron-jobs.yaml index 6fcc85631..912acb07c 100644 --- a/.github/workflows/cron-jobs.yaml +++ b/.github/workflows/cron-jobs.yaml @@ -3,6 +3,10 @@ name: Security and quality nightly scan on: schedule: - cron: '0 10 * * *' + pull_request: + paths: + - .github/workflows/cron-jobs.yaml + - .github/workflows/security-scan.yaml permissions: contents: read @@ -70,7 +74,6 @@ jobs: permissions: contents: read # for actions/checkout to fetch code security-events: write # for github/codeql-action/upload-sarif to upload SARIF results - runs-on: ubuntu-latest strategy: matrix: include: @@ -80,47 +83,7 @@ jobs: # Add branches to test here - { branch: release-1.30, channel: 1.30-classic/edge } - { branch: release-1.31, channel: 1.31-classic/edge } - - steps: - - name: Checking out repo - uses: actions/checkout@v4 - with: - ref: ${{matrix.branch}} - - name: Setup Trivy vulnerability scanner - run: | - mkdir -p sarifs - VER=$(curl --silent -qI https://github.com/aquasecurity/trivy/releases/latest | awk -F '/' '/^location/ {print substr($NF, 1, length($NF)-1)}'); - wget https://github.com/aquasecurity/trivy/releases/download/${VER}/trivy_${VER#v}_Linux-64bit.tar.gz - tar -zxvf ./trivy_${VER#v}_Linux-64bit.tar.gz - - name: Run Trivy vulnerability scanner in repo mode - uses: aquasecurity/trivy-action@master - with: - scan-type: "fs" - ignore-unfixed: true - format: "sarif" - output: "trivy-k8s-repo-scan--results.sarif" - severity: "MEDIUM,HIGH,CRITICAL" - env: - TRIVY_DB_REPOSITORY: "public.ecr.aws/aquasecurity/trivy-db" - - name: Gather Trivy repo scan results - run: | - cp trivy-k8s-repo-scan--results.sarif ./sarifs/ - - name: Run Trivy vulnerability scanner on the snap - run: | - snap download k8s --channel ${{ matrix.channel }} - mv ./k8s*.snap ./k8s.snap - unsquashfs k8s.snap - for var in $(env | grep -o '^TRIVY_[^=]*'); do - unset "$var" - done - ./trivy --db-repository public.ecr.aws/aquasecurity/trivy-db rootfs ./squashfs-root/ --format sarif > sarifs/snap.sarif - - name: Get HEAD sha - run: | - SHA="$(git rev-parse HEAD)" - echo "head_sha=$SHA" >> "$GITHUB_ENV" - - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: "sarifs" - sha: ${{ env.head_sha }} - ref: refs/heads/${{matrix.branch}} + uses: ./.github/workflows/security-scan.yaml + with: + channel: ${{ matrix.channel }} + checkout-ref: ${{ matrix.branch }} diff --git a/.github/workflows/e2e-tests.yaml b/.github/workflows/e2e-tests.yaml new file mode 100644 index 000000000..79d89b712 --- /dev/null +++ b/.github/workflows/e2e-tests.yaml @@ -0,0 +1,72 @@ +name: Run k8s-snap e2e tests + +on: + workflow_call: + inputs: + arch: + description: Job runner architecture (amd64 or arm64) + default: amd64 + type: string + os: + description: LXD image to use when running e2e tests + default: ubuntu:24.04 + type: string + # Download k8s-snap using either a GH action artifact or a snap channel. + artifact: + description: The name of a GH action artifact. + type: string + channel: + description: k8s snap channel. + type: string + test-tags: + description: Test filter tags (e.g. pull_request, up_to_weekly) + default: pull_request + type: string + +jobs: + test-integration: + name: Integration Test ${{ inputs.os }} ${{ inputs.arch }} ${{ inputs.artifact }} + runs-on: ${{ inputs.arch == 'arm64' && 'self-hosted-linux-arm64-jammy-large' || 'self-hosted-linux-amd64-jammy-large' }} + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + - name: Download k8s-snap + id: download-snap + uses: ./.github/actions/download-k8s-snap + with: + channel: ${{ inputs.channel }} + artifact: ${{ inputs.artifact }} + - name: Install lxd + uses: ./.github/actions/install-lxd + - name: Install tox + run: pip install tox + - name: Run e2e tests + env: + TEST_SNAP: ${{ steps.download-snap.outputs.snap-path }} + TEST_SUBSTRATE: lxd + TEST_LXD_IMAGE: ${{ inputs.os }} + TEST_INSPECTION_REPORTS_DIR: ${{ github.workspace }}/inspection-reports + # Test the latest (up to) 6 releases for the flavour + # TODO(ben): upgrade nightly to run all flavours + TEST_VERSION_UPGRADE_CHANNELS: "recent 6 classic" + # Upgrading from 1.30 is not supported. + TEST_VERSION_UPGRADE_MIN_RELEASE: "1.31" + TEST_STRICT_INTERFACE_CHANNELS: "recent 6 strict" + TEST_MIRROR_LIST: '[{"name": "ghcr.io", "port": 5000, "remote": "https://ghcr.io", "username": "${{ github.actor }}", "password": "${{ secrets.GITHUB_TOKEN }}"}, {"name": "docker.io", "port": 5001, "remote": "https://registry-1.docker.io", "username": "", "password": ""}, {"name": "rocks.canonical.com", "port": 5002, "remote": "https://rocks.canonical.com/cdk"}]' + run: | + cd tests/integration && sg lxd -c "tox -e integration -- --tags ${{ inputs.test-tags }}" + - name: Prepare inspection reports + if: failure() + run: | + tar -czvf inspection-reports.tar.gz -C ${{ github.workspace }} inspection-reports + echo "artifact_name=inspection-reports-${{ inputs.os }}" | sed 's/:/-/g' >> $GITHUB_ENV + - name: Upload inspection report artifact + if: failure() + uses: actions/upload-artifact@v4 + with: + name: ${{ env.artifact_name }} + path: ${{ github.workspace }}/inspection-reports.tar.gz diff --git a/.github/workflows/go.yaml b/.github/workflows/go.yaml index 725157b61..7f39a12c7 100644 --- a/.github/workflows/go.yaml +++ b/.github/workflows/go.yaml @@ -1,19 +1,7 @@ -name: Go +name: Go lint and unit tests on: - push: - paths-ignore: - - 'docs/**' - branches: - - main - - autoupdate/strict - - autoupdate/moonray - - 'release-[0-9]+.[0-9]+' - - 'autoupdate/release-[0-9]+.[0-9]+-strict' - - 'autoupdate/sync/**' - pull_request: - paths-ignore: - - 'docs/**' + workflow_call: permissions: contents: read diff --git a/.github/workflows/integration-informing.yaml b/.github/workflows/integration-informing.yaml deleted file mode 100644 index d569a7c66..000000000 --- a/.github/workflows/integration-informing.yaml +++ /dev/null @@ -1,104 +0,0 @@ -name: Informing Integration Tests - -on: - push: - paths-ignore: - - 'docs/**' - branches: - - main - - 'release-[0-9]+.[0-9]+' - - 'autoupdate/sync/**' - pull_request: - paths-ignore: - - 'docs/**' - -permissions: - contents: read - -jobs: - build: - name: Build ${{ matrix.patch }} - runs-on: ubuntu-20.04 - strategy: - matrix: - patch: ["moonray"] - fail-fast: false - steps: - - name: Checking out repo - uses: actions/checkout@v4 - - name: Install lxd - run: | - sudo snap refresh lxd --channel 5.21/stable - sudo lxd init --auto - sudo usermod --append --groups lxd $USER - sg lxd -c 'lxc version' - - name: Install snapcraft - run: | - sudo snap install snapcraft --classic - - name: Apply ${{ matrix.patch }} patch - run: | - ./build-scripts/patches/${{ matrix.patch }}/apply - - name: Build snap - run: | - sg lxd -c 'snapcraft --use-lxd' - mv k8s_*.snap k8s-${{ matrix.patch }}.snap - - name: Uploading snap - uses: actions/upload-artifact@v4 - with: - name: k8s-${{ matrix.patch }}.snap - path: k8s-${{ matrix.patch }}.snap - - test-integration: - needs: [ build ] - name: Test ${{ matrix.patch }} ${{ matrix.os }} - strategy: - matrix: - os: ["ubuntu:20.04"] - patch: ["moonray"] - fail-fast: false - runs-on: ["self-hosted", "Linux", "AMD64", "jammy", "large"] - steps: - - name: Check out code - uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.10' - - name: Install tox - run: pip install tox - - name: Install lxd - run: | - sudo snap refresh lxd --channel 5.21/stable - sudo lxd init --auto - sudo usermod --append --groups lxd $USER - sg lxd -c 'lxc version' - sudo iptables -I DOCKER-USER -i lxdbr0 -j ACCEPT - sudo iptables -I DOCKER-USER -o lxdbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT - - name: Download snap - uses: actions/download-artifact@v4 - with: - name: k8s-${{ matrix.patch }}.snap - path: ${{ github.workspace }}/build - - name: Apply ${{ matrix.patch }} patch - run: | - ./build-scripts/patches/${{ matrix.patch }}/apply - - name: Run end to end tests - env: - TEST_SNAP: ${{ github.workspace }}/build/k8s-${{ matrix.patch }}.snap - TEST_SUBSTRATE: lxd - TEST_LXD_IMAGE: ${{ matrix.os }} - TEST_FLAVOR: ${{ matrix.patch }} - TEST_INSPECTION_REPORTS_DIR: ${{ github.workspace }}/inspection-reports - run: | - cd tests/integration && sg lxd -c 'tox -e integration -- --tags pull_request' - - name: Prepare inspection reports - if: failure() - run: | - tar -czvf inspection-reports.tar.gz -C ${{ github.workspace }} inspection-reports - echo "artifact_name=inspection-reports-${{ matrix.os }}-${{ matrix.patch }}" | sed 's/:/-/g' >> $GITHUB_ENV - - name: Upload inspection report artifact - if: failure() - uses: actions/upload-artifact@v4 - with: - name: ${{ env.artifact_name }} - path: ${{ github.workspace }}/inspection-reports.tar.gz diff --git a/.github/workflows/integration.yaml b/.github/workflows/integration.yaml deleted file mode 100644 index 13857352e..000000000 --- a/.github/workflows/integration.yaml +++ /dev/null @@ -1,187 +0,0 @@ -name: Integration Tests - -on: - push: - paths-ignore: - - 'docs/**' - branches: - - main - - autoupdate/strict - - autoupdate/moonray - - 'release-[0-9]+.[0-9]+' - - 'autoupdate/release-[0-9]+.[0-9]+-strict' - - 'autoupdate/sync/**' - pull_request: - paths-ignore: - - 'docs/**' - -permissions: - contents: read - -jobs: - build: - name: Build - runs-on: ubuntu-20.04 - - steps: - - name: Checking out repo - uses: actions/checkout@v4 - - name: Install lxd - run: | - sudo snap refresh lxd --channel 5.21/stable - sudo lxd init --auto - sudo usermod --append --groups lxd $USER - sg lxd -c 'lxc version' - - name: Install snapcraft - run: | - sudo snap install snapcraft --classic - - name: Build snap - run: | - sg lxd -c 'snapcraft --use-lxd' - mv k8s_*.snap k8s.snap - - name: Uploading snap - uses: actions/upload-artifact@v4 - with: - name: k8s.snap - path: k8s.snap - - test-branches: - name: Test Branch Management - runs-on: ubuntu-20.04 - steps: - - name: Check out code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.8' - - name: Install tox - run: pip install tox - - name: Run branch_management tests - run: | - tox -c tests/branch_management -e test - - test-integration: - name: Test ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: ["ubuntu:20.04", "ubuntu:22.04", "ubuntu:24.04"] - runs-on: ["self-hosted", "Linux", "AMD64", "jammy", "large"] - needs: build - - steps: - - name: Check out code - uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.10' - - name: Install tox - run: pip install tox - - name: Install lxd - run: | - sudo snap refresh lxd --channel 5.21/stable - sudo lxd init --auto - sudo usermod --append --groups lxd $USER - sg lxd -c 'lxc version' - sudo iptables -I DOCKER-USER -i lxdbr0 -j ACCEPT - sudo iptables -I DOCKER-USER -o lxdbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT - - name: Download snap - uses: actions/download-artifact@v4 - with: - name: k8s.snap - path: ${{ github.workspace }}/build - - name: Run end to end tests - env: - TEST_SNAP: ${{ github.workspace }}/build/k8s.snap - TEST_SUBSTRATE: lxd - TEST_LXD_IMAGE: ${{ matrix.os }} - TEST_INSPECTION_REPORTS_DIR: ${{ github.workspace }}/inspection-reports - # Test the latest (up to) 6 releases for the flavour - # TODO(ben): upgrade nightly to run all flavours - TEST_VERSION_UPGRADE_CHANNELS: "recent 6 classic" - # Upgrading from 1.30 is not supported. - TEST_VERSION_UPGRADE_MIN_RELEASE: "1.31" - TEST_MIRROR_LIST: '[{"name": "ghcr.io", "port": 5000, "remote": "https://ghcr.io", "username": "${{ github.actor }}", "password": "${{ secrets.GITHUB_TOKEN }}"}, {"name": "docker.io", "port": 5001, "remote": "https://registry-1.docker.io", "username": "", "password": ""}, {"name": "rocks.canonical.com", "port": 5002, "remote": "https://rocks.canonical.com/cdk"}]' - run: | - tags="pull_request" - # Run all tests if there are test changes. In case of a PR, we'll - # get a merge commit that includes all changes. - if git diff HEAD HEAD~1 --name-only | grep "tests/"; then - tags="up_to_weekly" - fi - # Run all tests on backports. - if echo ${{ github.base_ref }} | grep "release-"; then - tags="up_to_weekly" - fi - cd tests/integration && sg lxd -c "tox -e integration -- --tags $tags" - - name: Prepare inspection reports - if: failure() - run: | - tar -czvf inspection-reports.tar.gz -C ${{ github.workspace }} inspection-reports - echo "artifact_name=inspection-reports-${{ matrix.os }}" | sed 's/:/-/g' >> $GITHUB_ENV - - name: Upload inspection report artifact - if: failure() - uses: actions/upload-artifact@v4 - with: - name: ${{ env.artifact_name }} - path: ${{ github.workspace }}/inspection-reports.tar.gz - - security-scan: - permissions: - contents: read # for actions/checkout to fetch code - security-events: write # for github/codeql-action/upload-sarif to upload SARIF results - name: Security scan - runs-on: ubuntu-20.04 - needs: build - steps: - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - # We run into rate limiting issues if we don't authenticate - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Checking out repo - uses: actions/checkout@v4 - - name: Fetch snap - uses: actions/download-artifact@v4 - with: - name: k8s.snap - path: build - - name: Setup Trivy vulnerability scanner - run: | - mkdir -p manual-trivy/sarifs - pushd manual-trivy - VER=$(curl --silent -qI https://github.com/aquasecurity/trivy/releases/latest | awk -F '/' '/^location/ {print substr($NF, 1, length($NF)-1)}'); - wget https://github.com/aquasecurity/trivy/releases/download/${VER}/trivy_${VER#v}_Linux-64bit.tar.gz - tar -zxvf ./trivy_${VER#v}_Linux-64bit.tar.gz - popd - - name: Run Trivy vulnerability scanner in repo mode - uses: aquasecurity/trivy-action@master - with: - scan-type: "fs" - ignore-unfixed: true - format: "sarif" - output: "trivy-k8s-repo-scan--results.sarif" - severity: "MEDIUM,HIGH,CRITICAL" - env: - TRIVY_DB_REPOSITORY: "public.ecr.aws/aquasecurity/trivy-db" - - name: Gather Trivy repo scan results - run: | - cp trivy-k8s-repo-scan--results.sarif ./manual-trivy/sarifs/ - - name: Run Trivy vulnerability scanner on the snap - run: | - for var in $(env | grep -o '^TRIVY_[^=]*'); do - unset "$var" - done - cp build/k8s.snap . - unsquashfs k8s.snap - ./manual-trivy/trivy --db-repository public.ecr.aws/aquasecurity/trivy-db rootfs ./squashfs-root/ --format sarif > ./manual-trivy/sarifs/snap.sarif - - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: "./manual-trivy/sarifs" diff --git a/.github/workflows/lint_and_integration.yaml b/.github/workflows/lint_and_integration.yaml new file mode 100644 index 000000000..1dffd9fe3 --- /dev/null +++ b/.github/workflows/lint_and_integration.yaml @@ -0,0 +1,139 @@ +name: Lint and integration tests + +on: + push: + paths-ignore: + - 'docs/**' + branches: + - main + - autoupdate/strict + - autoupdate/moonray + - 'release-[0-9]+.[0-9]+' + - 'autoupdate/release-[0-9]+.[0-9]+-strict' + - 'autoupdate/sync/**' + pull_request: + paths-ignore: + - 'docs/**' + +permissions: + contents: read + +jobs: + build-snap: + name: Build k8s-snap ${{ matrix.patch }} + uses: ./.github/workflows/build-snap.yaml + strategy: + matrix: + patch: ["", "moonray"] + with: + flavor: ${{ matrix.patch }} + + test-branches: + name: Test Branch Management + runs-on: ubuntu-20.04 + steps: + - name: Check out code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.8' + - name: Install tox + run: pip install tox + - name: Run branch_management tests + run: | + tox -c tests/branch_management -e test + + python-lint: + name: Python lint + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + - name: Install tox + run: pip install tox + - name: Lint + run: | + cd tests/integration && tox -e lint + + go-lint-and-unit: + name: Go lint and unit tests + uses: ./.github/workflows/go.yaml + permissions: + contents: read # for actions/checkout to fetch code + pull-requests: write # for marocchino/sticky-pull-request-comment to create or update PR comment + checks: write # for golangci/golangci-lint-action to checks to allow the action to annotate code in the PR. + + get-e2e-tags: + name: Get e2e test tags + runs-on: ubuntu-latest + outputs: + test-tags: ${{ steps.get-e2e-tags.outputs.test-tags }} + steps: + - name: Checking out repo + uses: actions/checkout@v4 + with: + fetch-depth: 2 + - name: Get e2e test tags + id: get-e2e-tags + run: | + tags="pull_request" + if ${{ github.event_name == 'pull_request' }}; then + # Run all tests if there are test changes. In case of a PR, we'll + # get a merge commit that includes all changes. + if git diff HEAD HEAD~1 --name-only | grep "tests/"; then + tags="up_to_weekly" + fi + # Run all tests on backports. + if echo ${{ github.base_ref }} | grep "release-"; then + tags="up_to_weekly" + fi + fi + + echo "test-tags=$tags" >> "$GITHUB_OUTPUT" + + test-integration: + name: Test ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: ["ubuntu:20.04", "ubuntu:22.04", "ubuntu:24.04"] + needs: [build-snap, get-e2e-tags, go-lint-and-unit, python-lint] + uses: ./.github/workflows/e2e-tests.yaml + with: + arch: amd64 + os: ${{ matrix.os }} + test-tags: ${{ needs.get-e2e-tags.outputs.test-tags}} + artifact: k8s.snap + + test-integration-informing: + name: Test informing ${{ matrix.os }} ${{ matrix.patch }} + strategy: + fail-fast: false + matrix: + os: ["ubuntu:20.04"] + patch: ["moonray"] + needs: [build-snap, get-e2e-tags, go-lint-and-unit, python-lint] + if: success() && github.event_name == 'pull_request' + uses: ./.github/workflows/e2e-tests.yaml + with: + arch: amd64 + os: ${{ matrix.os }} + test-tags: ${{ needs.get-e2e-tags.outputs.test-tags}} + artifact: k8s-${{ matrix.patch }}.snap + + security-scan: + name: Security scan + needs: build-snap + uses: ./.github/workflows/security-scan.yaml + with: + artifact: ${{ needs.build-snap.outputs.snap-artifact}} + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results diff --git a/.github/workflows/nightly-test.yaml b/.github/workflows/nightly-test.yaml index 98089d932..be37701f4 100644 --- a/.github/workflows/nightly-test.yaml +++ b/.github/workflows/nightly-test.yaml @@ -3,6 +3,10 @@ name: Nightly Latest/Edge Tests on: schedule: - cron: "0 0 * * *" # Runs every midnight + pull_request: + paths: + - .github/workflows/nightly-test.yaml + - .github/workflows/e2e-tests.yaml permissions: contents: read @@ -14,58 +18,11 @@ jobs: matrix: os: ["ubuntu:20.04", "ubuntu:22.04", "ubuntu:24.04"] arch: ["amd64", "arm64"] - release: ["latest/edge"] + channel: ["latest/edge"] fail-fast: false # TODO: remove once arm64 works - - runs-on: ${{ matrix.arch == 'arm64' && 'self-hosted-linux-arm64-jammy-large' || 'self-hosted-linux-amd64-jammy-large' }} - - steps: - - name: Checking out repo - uses: actions/checkout@v4 - - name: Install lxd and tox - run: | - sudo apt update - sudo apt install -y tox - sudo snap refresh lxd --channel 5.21/stable - sudo lxd init --auto - sudo usermod --append --groups lxd $USER - sg lxd -c 'lxc version' - sudo iptables -I DOCKER-USER -i lxdbr0 -j ACCEPT - sudo iptables -I DOCKER-USER -o lxdbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT - - name: Create build directory - run: mkdir -p build - - name: Install ${{ matrix.release }} k8s snap - run: | - cd build - snap download k8s --channel=${{ matrix.release }} --basename k8s - - name: Run end to end tests # tox path needs to be specified for arm64 - env: - TEST_SNAP: ${{ github.workspace }}/build/k8s.snap - TEST_SUBSTRATE: lxd - TEST_LXD_IMAGE: ${{ matrix.os }} - TEST_INSPECTION_REPORTS_DIR: ${{ github.workspace }}/inspection-reports - # Test the latest (up to) 6 releases for the flavour - # TODO(ben): upgrade nightly to run all flavours - TEST_VERSION_UPGRADE_CHANNELS: "recent 6 classic" - # Upgrading from 1.30 is not supported. - TEST_VERSION_UPGRADE_MIN_RELEASE: "1.31" - TEST_STRICT_INTERFACE_CHANNELS: "recent 6 strict" - TEST_MIRROR_LIST: '[{"name": "ghcr.io", "port": 5000, "remote": "https://ghcr.io", "username": "${{ github.actor }}", "password": "${{ secrets.GITHUB_TOKEN }}"}, {"name": "docker.io", "port": 5001, "remote": "https://registry-1.docker.io", "username": "", "password": ""}, {"name": "rocks.canonical.com", "port": 5002, "remote": "https://rocks.canonical.com/cdk"}]' - run: | - export PATH="/home/runner/.local/bin:$PATH" - cd tests/integration && sg lxd -c 'tox -vve integration -- --tags up_to_nightly ' - - name: Prepare inspection reports - if: failure() - run: | - tar -czvf inspection-reports.tar.gz -C ${{ github.workspace }} inspection-reports - echo "artifact_name=inspection-reports-${{ matrix.os }}-${{ matrix.arch }}" | sed 's/:/-/g' >> $GITHUB_ENV - - name: Upload inspection report artifact - if: failure() - uses: actions/upload-artifact@v4 - with: - name: ${{ env.artifact_name }} - path: ${{ github.workspace }}/inspection-reports.tar.gz - - name: Tmate debugging session - if: ${{ failure() && github.event_name == 'pull_request' }} - uses: mxschmitt/action-tmate@v3 - timeout-minutes: 10 + uses: ./.github/workflows/e2e-tests.yaml + with: + arch: ${{ matrix.arch }} + os: ${{ matrix.os }} + channel: ${{ matrix.channel }} + test-tags: 'up_to_weekly' diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml deleted file mode 100644 index c8cb71c85..000000000 --- a/.github/workflows/python.yaml +++ /dev/null @@ -1,37 +0,0 @@ -name: Python - -on: - push: - paths-ignore: - - 'docs/**' - branches: - - main - - autoupdate/strict - - autoupdate/moonray - - 'release-[0-9]+.[0-9]+' - - 'autoupdate/release-[0-9]+.[0-9]+-strict' - - 'autoupdate/sync/**' - pull_request: - paths-ignore: - - 'docs/**' - -permissions: - contents: read - -jobs: - lint: - name: Lint - runs-on: ubuntu-latest - - steps: - - name: Check out code - uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.10' - - name: Install tox - run: pip install tox - - name: Lint - run: | - cd tests/integration && tox -e lint diff --git a/.github/workflows/security-scan.yaml b/.github/workflows/security-scan.yaml new file mode 100644 index 000000000..6f12fca0a --- /dev/null +++ b/.github/workflows/security-scan.yaml @@ -0,0 +1,80 @@ +name: Security scan + +permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + +on: + workflow_call: + inputs: + # Download k8s-snap using either a GH action artifact or a snap channel. + artifact: + description: The name of a GH action artifact. + type: string + channel: + description: k8s snap channel. + type: string + checkout-ref: + description: k8s-snap git checkout ref, optional. + type: string + +jobs: + get-tags: + name: Security scan + runs-on: ubuntu-20.04 + steps: + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + # We run into rate limiting issues if we don't authenticate + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + # Need to fetch the GH actions first. + - name: Checking out repo + uses: actions/checkout@v4 + - name: Download k8s-snap + id: download-snap + uses: ./.github/actions/download-k8s-snap + with: + channel: ${{ inputs.channel }} + artifact: ${{ inputs.artifact }} + - name: Checking out tested repo branch + uses: actions/checkout@v4 + with: + ref: ${{ inputs.checkout-ref }} + # Persist downloaded artifacts + clean: 'false' + - name: Setup Trivy vulnerability scanner + run: | + mkdir -p manual-trivy/sarifs + pushd manual-trivy + VER=$(curl --silent -qI https://github.com/aquasecurity/trivy/releases/latest | awk -F '/' '/^location/ {print substr($NF, 1, length($NF)-1)}'); + wget https://github.com/aquasecurity/trivy/releases/download/${VER}/trivy_${VER#v}_Linux-64bit.tar.gz + tar -zxvf ./trivy_${VER#v}_Linux-64bit.tar.gz + popd + - name: Run Trivy vulnerability scanner in repo mode + uses: aquasecurity/trivy-action@master + with: + scan-type: "fs" + ignore-unfixed: true + format: "sarif" + output: "trivy-k8s-repo-scan--results.sarif" + severity: "MEDIUM,HIGH,CRITICAL" + env: + TRIVY_DB_REPOSITORY: "public.ecr.aws/aquasecurity/trivy-db" + - name: Gather Trivy repo scan results + run: | + cp trivy-k8s-repo-scan--results.sarif ./manual-trivy/sarifs/ + - name: Run Trivy vulnerability scanner on the snap + run: | + for var in $(env | grep -o '^TRIVY_[^=]*'); do + unset "$var" + done + cp ${{ steps.download-snap.outputs.snap-path }} ./k8s-test.snap + unsquashfs k8s-test.snap + ./manual-trivy/trivy --db-repository public.ecr.aws/aquasecurity/trivy-db rootfs ./squashfs-root/ --format sarif > ./manual-trivy/sarifs/snap.sarif + - name: Upload Trivy scan results to GitHub Security tab + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: "./manual-trivy/sarifs"