Add a metrics endpoint #158
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
| name: CI | |
| # The module, not the documentation. A change under docs/, a markdown file, or | |
| # a documentation workflow runs docs-pr.yml instead. | |
| on: | |
| pull_request: | |
| paths-ignore: | |
| - 'docs/**' | |
| - '**.md' | |
| - 'LICENSE' | |
| - 'NOTICE' | |
| - '.github/workflows/docs-*.yml' | |
| push: | |
| branches: | |
| - main | |
| paths-ignore: | |
| - 'docs/**' | |
| - '**.md' | |
| - 'LICENSE' | |
| - 'NOTICE' | |
| - '.github/workflows/docs-*.yml' | |
| permissions: | |
| contents: read | |
| packages: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| test: | |
| name: Test | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # No setup-buildx-action here on purpose. It installs a docker-container | |
| # builder, which cannot see images in the local store, so a toolchain | |
| # built by the fallback is invisible to the next build. The default | |
| # builder reads the local store. Multi-arch lives in builder.yml, which | |
| # is the one place that needs buildx. | |
| - name: Log in to the registry | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Run the suite | |
| run: make -C test test | |
| - name: Show the module log | |
| if: failure() | |
| run: make -C test logs | |
| - name: Upload rejected images | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: failed-golden-images | |
| path: test/golden/**/*.failed.* | |
| if-no-files-found: ignore | |
| golden: | |
| name: Golden files | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # No setup-buildx-action here on purpose. It installs a docker-container | |
| # builder, which cannot see images in the local store, so a toolchain | |
| # built by the fallback is invisible to the next build. The default | |
| # builder reads the local store. Multi-arch lives in builder.yml, which | |
| # is the one place that needs buildx. | |
| - name: Log in to the registry | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| # Regenerating must reproduce the bytes already in the tree. A diff here | |
| # means the output is not deterministic, which makes every golden case | |
| # meaningless. | |
| - name: Regenerate the goldens | |
| run: make -C test test-update | |
| - name: Check nothing changed | |
| run: | | |
| if ! git diff --quiet -- test/golden; then | |
| echo "Regenerating the golden files changed them." | |
| echo "The output is not deterministic, so every golden case is meaningless." | |
| git diff --stat -- test/golden | |
| exit 1 | |
| fi | |
| echo "every golden file reproduced exactly" | |
| arm64: | |
| name: Test arm64 | |
| runs-on: ubuntu-24.04-arm | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # No setup-buildx-action here on purpose. It installs a docker-container | |
| # builder, which cannot see images in the local store, so a toolchain | |
| # built by the fallback is invisible to the next build. The default | |
| # builder reads the local store. Multi-arch lives in builder.yml, which | |
| # is the one place that needs buildx. | |
| - name: Log in to the registry | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| # The golden files carry no architecture in their name, because amd64 | |
| # and arm64 were measured to produce all 90 byte for byte identical. | |
| # This job is what keeps that true: it runs the same cases against the | |
| # same baselines, so a divergence fails here instead of hiding in a | |
| # second set nothing compares. | |
| - name: Run the suite | |
| run: make -C test test | |
| - name: Show the module log | |
| if: failure() | |
| run: make -C test logs | |
| - name: Upload rejected images | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: failed-golden-images-arm64 | |
| path: test/golden/**/*.failed.* | |
| if-no-files-found: ignore | |
| image: | |
| name: Server image | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Log in to the registry | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| # Pull the toolchain, or build it. A pull request that bumps a pinned | |
| # version names a tag the registry does not have yet, because the | |
| # builder workflow publishes on the merge. Without this the two wait on | |
| # each other. | |
| - name: Pull the toolchain | |
| run: make toolchain | |
| - name: Build the server image | |
| run: | | |
| docker build -f docker/Dockerfile -t mod-dims:ci \ | |
| --build-arg DIMS_COMMIT="$(git rev-parse --short HEAD)" . | |
| # The image has to start with nothing set. Every DIMS_ variable has a | |
| # default, and a missing one makes httpd refuse to start. | |
| - name: Start the container | |
| run: | | |
| docker run -d --name dims-ci -p 8000:8000 mod-dims:ci | |
| for i in $(seq 30); do | |
| if curl -fsS -o /dev/null http://127.0.0.1:8000/dims-status/; then | |
| exit 0 | |
| fi | |
| sleep 1 | |
| done | |
| docker logs dims-ci | |
| exit 1 | |
| - name: Serve an image | |
| run: | | |
| docker run -d --name dims-origin \ | |
| -v "$PWD/test/origin:/usr/local/apache2/htdocs:ro" httpd:2.4.68 | |
| origin=$(docker inspect -f \ | |
| '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' dims-origin) | |
| docker rm -f dims-ci | |
| # The origin runs on a private network address, so this run opts in. | |
| docker run -d --name dims-ci \ | |
| -e DIMS_ENABLE_DIMS3=on \ | |
| -e DIMS_WHITELIST="$origin" \ | |
| -e DIMS_ALLOW_PRIVATE_ADDRESSES=on \ | |
| mod-dims:ci | |
| sleep 5 | |
| docker exec dims-ci curl -fsS -o /tmp/out.png \ | |
| "http://127.0.0.1:8000/dims3/development/resize/100x100/?url=http://$origin/grid.png" | |
| docker exec dims-ci sh -c 'test -s /tmp/out.png' | |
| # The metrics endpoint serves its own port, and only when the | |
| # environment turns it on. | |
| - name: Scrape the metrics endpoint | |
| run: | | |
| docker rm -f dims-ci | |
| docker run -d --name dims-ci -p 8001:8001 \ | |
| -e DIMS_METRICS_ENABLED=on mod-dims:ci | |
| for i in $(seq 30); do | |
| if curl -fsS -o /dev/null http://127.0.0.1:8001/metrics; then | |
| break | |
| fi | |
| sleep 1 | |
| done | |
| curl -fsS http://127.0.0.1:8001/metrics | grep -q dims_requests_total | |
| curl -fsS http://127.0.0.1:8001/metrics | grep -q dims_httpd_workers | |
| # The runtime user must not be able to rewrite the module it runs. | |
| - name: Check the file permissions | |
| run: | | |
| docker exec dims-ci sh -c ' | |
| test "$(id -u)" = 33 || exit 1 | |
| ! test -w /usr/local/apache2/modules/libmod_dims.so || exit 1 | |
| ! test -w /usr/local/apache2/conf/httpd.conf || exit 1' | |
| sanitizers: | |
| name: Sanitizers | |
| runs-on: ubuntu-24.04 | |
| # Findings C4, M9, and H10 are reads of uninitialized or out of bounds | |
| # memory. This job is where they surface. It does not block until the fixes | |
| # land, because the module reports them today. | |
| continue-on-error: true | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # No setup-buildx-action here on purpose. It installs a docker-container | |
| # builder, which cannot see images in the local store, so a toolchain | |
| # built by the fallback is invisible to the next build. The default | |
| # builder reads the local store. Multi-arch lives in builder.yml, which | |
| # is the one place that needs buildx. | |
| - name: Log in to the registry | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Run the unit cases | |
| run: make -C test sanitize |