Local-Bench UI: ollama serve hint, branded PDF export, response comparison, editable prompts, collapsible sections #45
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: Publish container | |
| # Builds the container, runs it, screenshots its web UI as a gate, then pushes | |
| # to GHCR. The marketplace manifest pins :latest, so every push to main republishes | |
| # :latest (plus an immutable :sha-<short> tag). | |
| on: | |
| push: | |
| branches: [main] | |
| tags: ["*"] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| concurrency: | |
| group: publish-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| IMAGE_NAME: ghcr.io/companionintelligence/ci-local-bench | |
| INTERNAL_PORT: "3000" | |
| jobs: | |
| publish: | |
| name: Build, screenshot-test, publish | |
| runs-on: ubuntu-22.04 | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Compute tags | |
| id: meta | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| short="$(git rev-parse --short HEAD)" | |
| echo "sha_tag=${IMAGE_NAME}:sha-${short}" >> "$GITHUB_OUTPUT" | |
| tags="${IMAGE_NAME}:latest,${IMAGE_NAME}:sha-${short}" | |
| if [ "${GITHUB_REF_TYPE}" = "tag" ]; then | |
| tags="${tags},${IMAGE_NAME}:${GITHUB_REF_NAME}" | |
| fi | |
| echo "tags=${tags}" >> "$GITHUB_OUTPUT" | |
| - name: Build image (load for testing) | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| load: true | |
| tags: ${{ steps.meta.outputs.sha_tag }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Start container | |
| run: docker run -d --name app -p 8080:${INTERNAL_PORT} ${{ steps.meta.outputs.sha_tag }} | |
| - name: Wait for HTTP | |
| run: | | |
| for i in $(seq 1 60); do | |
| code="$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8080/ || true)" | |
| if [ "$code" != "000" ] && [ "$code" -lt 500 ]; then echo "up ($code)"; exit 0; fi | |
| sleep 2 | |
| done | |
| echo "container never responded"; docker logs app; exit 1 | |
| - name: Setup Node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| - name: Container screenshot test | |
| run: | | |
| cd tests/container | |
| npm install | |
| npx playwright install --with-deps chromium | |
| APP_URL=http://localhost:8080 SCREENSHOT_PATH="$GITHUB_WORKSPACE/screenshot.png" npx playwright test | |
| - name: Upload screenshot | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: container-screenshot | |
| path: screenshot.png | |
| if-no-files-found: warn | |
| - name: Container logs (on failure) | |
| if: failure() | |
| run: docker logs app || true | |
| - name: Tear down container | |
| if: always() | |
| run: docker rm -f app || true | |
| - name: Log in to GHCR | |
| if: github.event_name != 'pull_request' | |
| run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.repository_owner }}" --password-stdin | |
| - name: Build and push | |
| if: github.event_name != 'pull_request' | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| push: true | |
| platforms: linux/amd64,linux/arm64 | |
| tags: ${{ steps.meta.outputs.tags }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max |