Docker Browser Build #73
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: Docker Browser Build | |
| on: | |
| push: | |
| branches: | |
| - master | |
| - release | |
| - beta | |
| paths: | |
| - 'Dockerfile.browser' | |
| - 'src/server.ts' | |
| - 'src/AuthManager.ts' | |
| - 'app/**' | |
| - 'backend/**' | |
| - 'package.json' | |
| - 'yarn.lock' | |
| - '.github/workflows/docker-browser.yml' | |
| - 'tsconfig.json' | |
| - 'events/**' | |
| schedule: | |
| # Run every two weeks (1st and 15th of each month) at 2:00 AM UTC | |
| - cron: '0 2 1,15 * *' | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| build-and-test: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| id-token: write | |
| env: | |
| TESTS_MQTT_BROKER_HOST: localhost | |
| TESTS_MQTT_BROKER_PORT: 1883 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install and Start Mosquitto | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y mosquitto mosquitto-clients | |
| # Create a minimal configuration file for testing | |
| sudo tee /etc/mosquitto/conf.d/test.conf > /dev/null <<EOF | |
| listener 1883 | |
| allow_anonymous true | |
| persistence false | |
| EOF | |
| # Start mosquitto in detached mode | |
| sudo mosquitto -c /etc/mosquitto/mosquitto.conf -d | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Log in to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata (tags, labels) for Docker | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ghcr.io/${{ github.repository }} | |
| tags: | | |
| type=ref,event=branch | |
| type=sha,prefix={{branch}}- | |
| type=raw,value=latest,enable={{is_default_branch}} | |
| - name: Build Docker image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./Dockerfile.browser | |
| platforms: linux/amd64 | |
| push: false | |
| load: true | |
| tags: mqtt-explorer:test | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Test Docker image - Basic startup | |
| run: | | |
| # Start container with test credentials | |
| docker run -d \ | |
| --name mqtt-explorer-test \ | |
| -p 3000:3000 \ | |
| -e MQTT_EXPLORER_USERNAME=test \ | |
| -e MQTT_EXPLORER_PASSWORD=test123 \ | |
| -e PORT=3000 \ | |
| mqtt-explorer:test | |
| # Wait for server to be ready (max 60 seconds) | |
| echo "Waiting for server to start..." | |
| for i in {1..60}; do | |
| if curl -f http://localhost:3000 > /dev/null 2>&1; then | |
| echo "Server started successfully after $i seconds" | |
| break | |
| fi | |
| if [ $i -eq 60 ]; then | |
| echo "Server failed to start within 60 seconds" | |
| docker logs mqtt-explorer-test | |
| exit 1 | |
| fi | |
| sleep 1 | |
| done | |
| - name: Test Docker image - Health check | |
| run: | | |
| # Wait for health check to pass | |
| echo "Waiting for health check to pass..." | |
| for i in {1..30}; do | |
| health=$(docker inspect --format='{{.State.Health.Status}}' mqtt-explorer-test) | |
| if [ "$health" = "healthy" ]; then | |
| echo "Container is healthy" | |
| break | |
| fi | |
| if [ $i -eq 30 ]; then | |
| echo "Health check failed" | |
| docker logs mqtt-explorer-test | |
| exit 1 | |
| fi | |
| sleep 2 | |
| done | |
| - name: Test Docker image - Verify response | |
| run: | | |
| # Test that the server responds with HTML | |
| response=$(curl -s http://localhost:3000) | |
| if echo "$response" | grep -q "MQTT Explorer"; then | |
| echo "Server is serving the application correctly" | |
| else | |
| echo "Server response does not contain expected content" | |
| echo "Response: $response" | |
| exit 1 | |
| fi | |
| - name: Test Docker image - Verify data persistence | |
| run: | | |
| # Check that data directory was created | |
| docker exec mqtt-explorer-test sh -c '[ -d /app/data ] && echo "Data directory exists"' | |
| - name: Clean up test container | |
| if: always() | |
| run: | | |
| docker stop mqtt-explorer-test || true | |
| docker rm mqtt-explorer-test || true | |
| - name: Check Docker image size | |
| run: | | |
| echo "### Docker Image Size" >> $GITHUB_STEP_SUMMARY | |
| docker images mqtt-explorer:test --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" >> $GITHUB_STEP_SUMMARY | |
| # Get size in bytes for detailed reporting | |
| SIZE_BYTES=$(docker inspect mqtt-explorer:test --format='{{.Size}}') | |
| SIZE_MB=$((SIZE_BYTES / 1024 / 1024)) | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Image size**: ${SIZE_MB} MB (${SIZE_BYTES} bytes)" >> $GITHUB_STEP_SUMMARY | |
| echo "Image size: ${SIZE_MB} MB" | |
| - name: Setup Node.js for browser tests | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '24' | |
| cache: 'yarn' | |
| - name: Install dependencies for browser tests | |
| run: yarn install --frozen-lockfile | |
| - name: Install Playwright Browsers | |
| run: npx playwright install --with-deps chromium | |
| - name: Start Docker container for browser tests | |
| run: | | |
| docker run -d \ | |
| --name mqtt-explorer-browser-test \ | |
| --network host \ | |
| -e MQTT_EXPLORER_USERNAME=test \ | |
| -e MQTT_EXPLORER_PASSWORD=test123 \ | |
| -e PORT=3000 \ | |
| mqtt-explorer:test | |
| # Wait for server to be ready | |
| echo "Waiting for Docker container to be ready..." | |
| timeout 60 bash -c 'until curl -f http://localhost:3000; do sleep 1; done' | |
| echo "Docker container is ready" | |
| - name: Run browser test suite | |
| run: | | |
| yarn test:browser | |
| env: | |
| MQTT_EXPLORER_USERNAME: test | |
| MQTT_EXPLORER_PASSWORD: test123 | |
| BROWSER_MODE_URL: http://localhost:3000 | |
| - name: Clean up browser test container | |
| if: always() | |
| run: | | |
| docker logs mqtt-explorer-browser-test || true | |
| docker stop mqtt-explorer-browser-test || true | |
| docker rm mqtt-explorer-browser-test || true | |
| - name: Build and push Docker image | |
| id: build | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| file: ./Dockerfile.browser | |
| platforms: linux/amd64,linux/arm64,linux/arm/v7 | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Generate artifact attestation | |
| uses: actions/attest-build-provenance@v1 | |
| with: | |
| subject-name: ghcr.io/${{ github.repository }} | |
| subject-digest: ${{ steps.build.outputs.digest }} | |
| push-to-registry: true |