test: raise custom-exporter coverage to 90 (entrypoint, run_server, r… #30
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: Build images | |
| on: | |
| pull_request: | |
| push: | |
| branches: [main] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| packages: write | |
| env: | |
| REGISTRY: ghcr.io | |
| REGISTRY_NAMESPACE: ${{ github.repository_owner }} | |
| jobs: | |
| # Compute which buildable units a change touched → JSON matrix. | |
| detect: | |
| name: Detect affected | |
| runs-on: ubuntu-latest | |
| outputs: | |
| units: ${{ steps.affected.outputs.units }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # need history to diff against the base | |
| - name: Set up uv | |
| uses: astral-sh/setup-uv@v5 | |
| with: | |
| enable-cache: true | |
| - name: Install ci tooling | |
| run: uv sync | |
| - name: Compute affected units | |
| id: affected | |
| run: | | |
| set -euo pipefail | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| base="${{ github.event.pull_request.base.sha }}" | |
| else | |
| base="${{ github.event.before }}" | |
| fi | |
| # All-zeros (first push / force-push) or unresolvable base → build everything. | |
| if [ -z "$base" ] || [ "$base" = "0000000000000000000000000000000000000000" ] \ | |
| || ! git cat-file -e "${base}^{commit}" 2>/dev/null; then | |
| files=".github/workflows/build.yml" # matches TOOLING_GLOBS → all units | |
| else | |
| files="$(git diff --name-only "$base"...HEAD)" | |
| fi | |
| units="$(printf '%s\n' "$files" | uv run ci affected .)" | |
| echo "units=$units" >> "$GITHUB_OUTPUT" | |
| echo "Affected: $units" | |
| # One job per affected image. PR builds (no push); main pushes :sha + :latest. | |
| build: | |
| name: Build ${{ matrix.service }} | |
| needs: detect | |
| if: needs.detect.outputs.units != '[]' | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: ${{ fromJSON(needs.detect.outputs.units) }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up uv | |
| uses: astral-sh/setup-uv@v5 | |
| with: | |
| enable-cache: true | |
| - name: Test ${{ matrix.service }} | |
| # Runs unit + integration together; the project's --cov-fail-under applies | |
| # to their COMBINED coverage. e2e is orchestration-heavy and runs separately | |
| # (e2e.yml / `ci test --tier e2e`). Keyed on the build context so multi-image | |
| # stacks test the right subtree; no-ops for units with no pyproject (devbox). | |
| run: uv run ci test "${{ matrix.context }}" | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to ghcr.io | |
| if: github.event_name != 'pull_request' | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build${{ github.event_name != 'pull_request' && ' & push' || '' }} ${{ matrix.image_name }} | |
| run: | | |
| set -euo pipefail | |
| repo="${REGISTRY}/${REGISTRY_NAMESPACE}/${{ matrix.image_name }}" | |
| # bake resolves relative context/dockerfile from CWD, so run it from | |
| # the compose file's directory (compose-relative paths then resolve). | |
| cd "$(dirname "${{ matrix.compose_file }}")" | |
| compose="$(basename "${{ matrix.compose_file }}")" | |
| # --allow fs.read: some units (devbox consumers) build from a context | |
| # outside the compose dir (../../../images/devbox), which bake gates. | |
| args=(buildx bake -f "$compose" "${{ matrix.service }}" --allow "fs.read=*" | |
| --set "${{ matrix.service }}.cache-from=type=gha,scope=${{ matrix.image_name }}" | |
| --set "${{ matrix.service }}.cache-to=type=gha,mode=max,scope=${{ matrix.image_name }}") | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| # Gate only — build, don't push. | |
| args+=(--set "${{ matrix.service }}.output=type=cacheonly") | |
| docker "${args[@]}" | |
| else | |
| # Push the compose image tag (:latest), then add the immutable :sha | |
| # as a server-side retag. (bake --set tags= doesn't split a comma list.) | |
| args+=(--push) | |
| docker "${args[@]}" | |
| docker buildx imagetools create "${repo}:latest" --tag "${repo}:${GITHUB_SHA}" | |
| fi | |
| # Always-run required check: green when nothing built, red if any build failed. | |
| # This (not the matrix) is what branch protection should require — a path-filtered | |
| # matrix that is empty for an unrelated PR would otherwise never report. | |
| gate: | |
| name: Build gate | |
| needs: [detect, build] | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Verify builds | |
| run: | | |
| if [ "${{ needs.build.result }}" = "failure" ] || [ "${{ needs.build.result }}" = "cancelled" ]; then | |
| echo "A build job failed."; exit 1 | |
| fi | |
| echo "All affected builds passed (or nothing to build)." |