dev.yml #4321
Workflow file for this run
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
| # The primary point of this workflow is to ensure that the developer experience is good. | |
| # We take a very vanilla ubuntu image, install all necessary dependencies via "normal" means, | |
| # and then run the build and test steps as described in the README.md file. | |
| # The artifacts produced by these builds are not intended to be used for anything other than | |
| # ensuring that the developer experience is good. | |
| # Production artifacts are produced in a sterile environment (in another CI workflow). | |
| name: "dev.yml" | |
| on: | |
| pull_request: {} | |
| push: | |
| branches: | |
| - "main" | |
| tags: | |
| - "v*" | |
| merge_group: | |
| types: ["checks_requested"] | |
| workflow_dispatch: | |
| inputs: | |
| debug_enabled: | |
| type: "boolean" | |
| description: "Run with tmate enabled" | |
| required: false | |
| default: false | |
| debug_justfile: | |
| type: "boolean" | |
| description: "enable to see debug statements from just recipes" | |
| required: false | |
| default: false | |
| skip_vlab_tests: | |
| type: "boolean" | |
| description: "Skip VLAB tests (they run by default)" | |
| required: false | |
| default: false | |
| run_hlab_tests: | |
| type: "boolean" | |
| description: "Run hybrid HLAB tests" | |
| required: false | |
| default: false | |
| enable_release_tests: | |
| type: "boolean" | |
| description: "Enable release tests for VLAB/HLAB tests" | |
| required: false | |
| default: false | |
| concurrency: | |
| group: "${{ github.workflow }}:${{ github.event.pull_request.number || github.event.after || github.event.merge_group && github.run_id }}" | |
| cancel-in-progress: true | |
| permissions: | |
| contents: "read" | |
| packages: "write" | |
| id-token: "write" | |
| jobs: | |
| check_changes: | |
| name: "Deduce required tests from code changes" | |
| permissions: | |
| contents: "read" | |
| pull-requests: "read" | |
| runs-on: "ubuntu-latest" | |
| outputs: | |
| devfiles: "${{ steps.changes.outputs.devfiles }}" | |
| steps: | |
| - name: "Checkout" | |
| if: "${{ !github.event.pull_request }}" | |
| uses: "actions/checkout@v6" | |
| with: | |
| persist-credentials: "false" | |
| fetch-depth: "0" | |
| - name: "Check code changes" | |
| uses: "dorny/paths-filter@v3" | |
| id: "changes" | |
| with: | |
| filters: | | |
| devfiles: | |
| - '!(README.md|LICENSE|.gitignore|.github/**)' | |
| - '.github/workflows/dev.yml' | |
| check: | |
| needs: [check_changes] | |
| if: "${{ needs.check_changes.outputs.devfiles == 'true' || startsWith(github.event.ref, 'refs/tags/v') && github.event_name == 'push' }}" | |
| permissions: | |
| checks: "write" | |
| pull-requests: "write" | |
| contents: "read" | |
| packages: "write" | |
| id-token: "write" | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| profile: | |
| - name: "debug" | |
| sterile: "" | |
| - name: "debug" | |
| sterile: "sterile" | |
| - name: "release" | |
| sterile: "sterile" | |
| - name: "fuzz" | |
| sterile: "sterile" | |
| #- name: "release" | |
| # sterile: "" | |
| #- name: "fuzz" | |
| # sterile: "" | |
| debug_justfile: | |
| - "${{ inputs.debug_justfile || false }}" | |
| name: "${{matrix.profile.name}} ${{matrix.profile.sterile}}" | |
| runs-on: "lab" | |
| timeout-minutes: 45 | |
| steps: | |
| - name: "login to ghcr.io" | |
| uses: "docker/login-action@v3" | |
| with: | |
| registry: "ghcr.io" | |
| username: "${{ github.actor }}" | |
| password: "${{ secrets.GITHUB_TOKEN }}" | |
| - name: "Checkout" | |
| uses: "actions/checkout@v6" | |
| with: | |
| persist-credentials: "false" | |
| fetch-depth: "0" | |
| - name: "install just" | |
| run: | | |
| # this keeps our GH actions logs from getting messed up with color codes | |
| echo 'deb [trusted=yes] https://apt.gabe565.com /' | sudo tee /etc/apt/sources.list.d/gabe565.list | |
| sudo apt-get update | |
| sudo apt-get install --yes --no-install-recommends just | |
| - name: "set up build environment" | |
| run: | | |
| REQUIRED_HUGEPAGES=512 | |
| HUGEPAGES_PATH=/sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages | |
| OVERCOMMIT_HUGEPAGES_PATH=/sys/kernel/mm/hugepages/hugepages-2048kB/nr_overcommit_hugepages | |
| docker run --privileged --rm busybox:latest sh -c "echo $((6 * REQUIRED_HUGEPAGES)) > $OVERCOMMIT_HUGEPAGES_PATH" | |
| docker run --privileged --rm busybox:latest sh -c "echo $((2 * REQUIRED_HUGEPAGES)) > $HUGEPAGES_PATH" | |
| docker pull ghcr.io/githedgehog/testn/n-vm:v0.0.9 | |
| just --yes \ | |
| debug_justfile="${{matrix.debug_justfile}}" \ | |
| profile=${{matrix.profile.name}} \ | |
| refresh-compile-env | |
| just --yes debug_justfile="${{matrix.debug_justfile}}" fake-nix | |
| - name: "cargo deny check" | |
| run: | | |
| just \ | |
| debug_justfile="${{matrix.debug_justfile}}" \ | |
| profile=${{matrix.profile.name}} \ | |
| ${{matrix.profile.sterile}} cargo deny check | |
| - name: "push container" | |
| if: ${{ matrix.profile.sterile == 'sterile' && (matrix.profile.name == 'release' || matrix.profile.name == 'debug') }} | |
| run: | | |
| just \ | |
| debug_justfile="${{matrix.debug_justfile}}" \ | |
| profile=${{matrix.profile.name}} \ | |
| target=x86_64-unknown-linux-gnu \ | |
| push-container | |
| - name: "print container image name" | |
| if: ${{ matrix.profile.sterile == 'sterile' && (matrix.profile.name == 'release' || matrix.profile.name == 'debug') }} | |
| run: | | |
| just \ | |
| debug_justfile="${{matrix.debug_justfile}}" \ | |
| profile=${{matrix.profile.name}} \ | |
| target=x86_64-unknown-linux-gnu \ | |
| print-container-tags | |
| - id: "test" | |
| name: "test" | |
| run: | | |
| set -euo pipefail | |
| mkdir --parent ./target/nextest | |
| # Run tests. The resulting results.json is not a full JSON object but | |
| # a list of JSON objects, one per line. | |
| if [ ${{ matrix.profile.name }} = "fuzz" ]; then | |
| echo "::notice::Running fuzz tests" | |
| just \ | |
| debug_justfile="${{matrix.debug_justfile}}" \ | |
| profile=${{matrix.profile.name}} \ | |
| target=x86_64-unknown-linux-gnu \ | |
| ${{matrix.profile.sterile}} coverage \ | |
| --status-level=none \ | |
| --final-status-level=skip \ | |
| --message-format=libtest-json-plus > ./results.json | |
| else | |
| echo "::notice::Running regular tests" | |
| just \ | |
| debug_justfile="${{matrix.debug_justfile}}" \ | |
| profile=${{matrix.profile.name}} \ | |
| target=x86_64-unknown-linux-gnu \ | |
| ${{matrix.profile.sterile}} cargo nextest run \ | |
| --cargo-profile=${{matrix.profile.name}} \ | |
| --status-level=none \ | |
| --final-status-level=skip \ | |
| --message-format=libtest-json-plus \ | |
| > ./results.json | |
| echo "::notice::Running Shuttle tests" | |
| # We need to rebuild using the shuttle feature. To avoid running | |
| # all tests a second time, we filter to run only tests with pattern | |
| # "shuttle" in their name (test function name, file name, or module | |
| # name). | |
| # | |
| # IF YOUR SHUTTLE TESTS DO NOT HAVE "shuttle" IN THEIR NAME, THEY | |
| # WILL NOT RUN. | |
| just \ | |
| debug_justfile="${{matrix.debug_justfile}}" \ | |
| profile=${{matrix.profile.name}} \ | |
| target=x86_64-unknown-linux-gnu \ | |
| ${{matrix.profile.sterile}} cargo nextest run \ | |
| --cargo-profile=${{matrix.profile.name}} \ | |
| --status-level=none \ | |
| --final-status-level=none \ | |
| --message-format=libtest-json-plus \ | |
| --features shuttle \ | |
| shuttle \ | |
| >> ./results.json | |
| fi | |
| # look for any flakes (flakes have a #\\d+ match in their name field) | |
| jq \ | |
| --raw-output \ | |
| --slurp '.[] | select(.type == "test" and (.name | test(".*#\\d+"))) | ( .name | split("#") ) | | |
| [.[0], (.[1] | tonumber)] | @csv | |
| ' ./results.json > ./target/nextest/flakes.csv | |
| if [ -s ./target/nextest/flakes.csv ]; then | |
| { | |
| echo "FLAKY_TESTS<<EOF" | |
| echo -e "### :warning: Flaky tests (${{matrix.profile.name}} - ${{matrix.profile.sterile}})\n"; | |
| echo "| test | retries |" | |
| echo "|------|---------|" | |
| just cargo csview --style=markdown --no-headers --body-align=left ./target/nextest/flakes.csv; | |
| echo "EOF" | |
| } >> "${GITHUB_ENV}" | |
| fi | |
| rm results.json | |
| - name: "upload test results to codecov" | |
| if: ${{ always() }} | |
| uses: "codecov/codecov-action@v5" | |
| with: | |
| fail_ci_if_error: true | |
| files: ./target/nextest/default/junit.xml | |
| report_type: "test_results" | |
| disable_search: "true" | |
| use_oidc: "true" | |
| verbose: true | |
| flags: "${{matrix.profile.name}}-${{ matrix.profile.sterile || 'developer' }}" | |
| - name: "upload codecov analysis" | |
| if: ${{ matrix.profile.name == 'fuzz' }} | |
| uses: "codecov/codecov-action@v5" | |
| with: | |
| fail_ci_if_error: true | |
| files: ./target/nextest/coverage/codecov.json | |
| report_type: "coverage" | |
| disable_search: "true" | |
| use_oidc: "true" | |
| verbose: true | |
| flags: "${{matrix.profile.name}}-${{ matrix.profile.sterile || 'developer' }}" | |
| - name: "clean up coverage data" | |
| run: | | |
| rm -f codecov codecov.SHA256SUM codecov.SHA256SUM.sig | |
| - uses: "marocchino/sticky-pull-request-comment@v2" | |
| if: ${{ always() }} | |
| with: | |
| header: "flakes_${{matrix.profile.name}}_${{matrix.profile.sterile}}" | |
| ignore_empty: "true" | |
| message: | | |
| ${{ env.FLAKY_TESTS }} | |
| - name: "publish test report" | |
| uses: "mikepenz/action-junit-report@v6" | |
| if: "${{ always() }}" | |
| with: | |
| annotate_notice: "false" | |
| annotate_only: "false" | |
| check_annotations: "true" | |
| check_retries: "false" | |
| comment: "false" | |
| detailed_summary: "true" | |
| fail_on_failure: "false" | |
| fail_on_parse_error: "true" | |
| flaky_summary: "true" | |
| include_empty_in_summary: "true" | |
| include_passed: "true" | |
| include_time_in_summary: "true" | |
| report_paths: "target/nextest/default/*junit.xml" | |
| require_passed_tests: "true" | |
| require_tests: "true" | |
| simplified_summary: "true" | |
| truncate_stack_traces: "false" | |
| group_reports: "true" | |
| check_name: "test-report-${{matrix.profile.name}}-sterile:${{matrix.profile.sterile == 'sterile'}}" | |
| skip_success_summary: "false" | |
| job_summary: "true" | |
| verbose_summary: "false" | |
| - id: "clippy" | |
| name: "run clippy" | |
| run: | | |
| just debug_justfile="${{matrix.debug_justfile}}" profile=${{matrix.profile.name}} \ | |
| ${{matrix.profile.sterile}} cargo clippy --all-targets --all-features -- -D warnings | |
| - id: "docs" | |
| name: "run rustdoc" | |
| run: | | |
| RUSTDOCFLAGS="-D warnings" just \ | |
| debug_justfile="${{matrix.debug_justfile}}" \ | |
| profile=${{matrix.profile.name}} \ | |
| target=x86_64-unknown-linux-gnu \ | |
| ${{matrix.profile.sterile}} cargo doc --no-deps | |
| - name: "Setup tmate session for debug" | |
| if: ${{ failure() && github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} | |
| uses: "mxschmitt/action-tmate@v3" | |
| timeout-minutes: 60 | |
| with: | |
| limit-access-to-actor: true | |
| vlab: | |
| if: "${{ needs.check_changes.outputs.devfiles == 'true' || startsWith(github.event.ref, 'refs/tags/v') && github.event_name == 'push' }}" | |
| needs: | |
| - check | |
| name: "${{ matrix.hybrid && 'h' || 'v' }}-${{ matrix.upgradefrom && 'up' || '' }}${{ matrix.upgradefrom }}${{ matrix.upgradefrom && '-' || '' }}${{ matrix.mesh && 'mesh-' || '' }}${{ matrix.gateway && 'gw-' || '' }}${{ matrix.includeonie && 'onie-' || '' }}${{ matrix.buildmode }}-${{ matrix.vpcmode }}" | |
| uses: githedgehog/fabricator/.github/workflows/run-vlab.yaml@master | |
| with: | |
| # ci:+hlab is required to enable hybrid lab tests on PR | |
| # ci:-vlab disables virtual lab tests on PR | |
| # ci:-upgrade disables upgrade tests on PR | |
| # hlab is disabled for main and merge_queue till we have gateway tests for it | |
| skip: >- | |
| ${{ | |
| github.event_name == 'pull_request' | |
| && ( | |
| matrix.hybrid && !contains(github.event.pull_request.labels.*.name, 'ci:+hlab') | |
| || !matrix.hybrid && contains(github.event.pull_request.labels.*.name, 'ci:-vlab') | |
| ) && ( | |
| matrix.upgradefrom == '' || contains(github.event.pull_request.labels.*.name, 'ci:-upgrade') | |
| ) | |
| || github.event_name == 'workflow_dispatch' | |
| && ( | |
| matrix.hybrid && inputs.run_hlab_tests != true | |
| || !matrix.hybrid && inputs.skip_vlab_tests == true | |
| ) | |
| || (github.event_name == 'push' || github.event_name == 'merge_group') | |
| && matrix.hybrid | |
| }} | |
| fabricatorref: master | |
| prebuild: "just bump dataplane x86_64-unknown-linux-gnu.release.${{ github.sha }}" | |
| fabricmode: ${{ matrix.fabricmode }} | |
| gateway: ${{ matrix.gateway }} | |
| includeonie: ${{ matrix.includeonie }} | |
| buildmode: ${{ matrix.buildmode }} | |
| vpcmode: ${{ matrix.vpcmode }} | |
| releasetest: ${{ contains(github.event.pull_request.labels.*.name, 'ci:+release') || inputs.enable_release_tests == true }} | |
| hybrid: ${{ matrix.hybrid }} | |
| upgradefrom: ${{ matrix.upgradefrom }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| fabricmode: | |
| - spine-leaf | |
| gateway: | |
| - true | |
| includeonie: | |
| - false | |
| buildmode: | |
| - iso | |
| vpcmode: | |
| - l2vni | |
| hybrid: | |
| - false | |
| upgradefrom: | |
| - "" | |
| - "25.05" | |
| include: | |
| # gateway l3vni | |
| - fabricmode: spine-leaf | |
| gateway: true | |
| includeonie: false | |
| buildmode: iso | |
| vpcmode: l3vni | |
| hybrid: false | |
| upgradefrom: "" | |
| # hlab gateway l2vni | |
| - fabricmode: spine-leaf | |
| gateway: true | |
| includeonie: false | |
| buildmode: iso | |
| vpcmode: l2vni | |
| hybrid: true | |
| upgradefrom: "" | |
| summary: | |
| name: "Summary" | |
| runs-on: "ubuntu-latest" | |
| needs: | |
| - check | |
| - vlab | |
| # Run always, except when the "check" job was skipped. | |
| # | |
| # When the check job is skipped, summary will be marked as skipped, and | |
| # it's OK for CI (it's not a failure). | |
| # Why don't we do the same for check jobs? Because their names depend on | |
| # matrix values, and if we skip them the names won't be generated and | |
| # GitHub won't be able to find skipped jobs for required status checks. | |
| if: ${{ always() }} | |
| steps: | |
| - name: "Flag any check matrix failures" | |
| if: ${{ needs.check.result != 'success' && needs.check.result != 'skipped' }} | |
| run: | | |
| echo '::error:: Some check job(s) failed' | |
| exit 1 | |
| - name: "Flag any vlab matrix failures" | |
| if: ${{ needs.vlab.result != 'success' && needs.vlab.result != 'skipped' }} | |
| run: | | |
| echo '::error:: Some vlab job(s) failed' | |
| exit 1 | |
| publish: | |
| runs-on: lab | |
| if: startsWith(github.event.ref, 'refs/tags/v') && github.event_name == 'push' | |
| needs: | |
| - check | |
| - vlab | |
| permissions: | |
| packages: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Go | |
| uses: actions/setup-go@v6 | |
| with: | |
| go-version: stable | |
| cache: true | |
| - name: Login to ghcr.io | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Push release container | |
| run: | | |
| just push-release-container | |
| # Bump dataplane in the fabricator repository | |
| - name: Checkout fabricator repository | |
| uses: actions/checkout@v6 | |
| with: | |
| repository: githedgehog/fabricator | |
| path: fab-repo | |
| persist-credentials: false | |
| - name: Bump dataplane in fabricator | |
| working-directory: fab-repo | |
| run: | | |
| sed -i "s/^\tDataplaneVersion.*/\tDataplaneVersion=meta.Version(\"${{ github.ref_name }}\")/" pkg/fab/versions.go | |
| go fmt pkg/fab/versions.go | |
| - name: Generate token for the fabricator repository | |
| uses: actions/create-github-app-token@v2 | |
| id: fab-app-token | |
| with: | |
| app-id: ${{ secrets.FAB_APP_ID }} | |
| private-key: ${{ secrets.FAB_PRIVATE_KEY }} | |
| repositories: | | |
| fabricator | |
| - name: Create Pull Request for fabricator | |
| uses: peter-evans/create-pull-request@v7 | |
| id: fab-pr | |
| with: | |
| token: ${{ steps.fab-app-token.outputs.token }} | |
| path: fab-repo | |
| branch: pr/auto/dataplane-bump | |
| commit-message: | | |
| bump: dataplane to ${{ github.ref_name }} | |
| This is an automated commit created by GitHub Actions workflow, | |
| in the dataplane repository. | |
| signoff: true | |
| title: "bump: dataplane to ${{ github.ref_name }}" | |
| body: | | |
| This is an automated Pull Request created by GitHub Actions workflow, | |
| in the dataplane repository. |