Skip to content

v2.6.8 - ESLint 10 stabilization and TS 6.0 compatibility #291

v2.6.8 - ESLint 10 stabilization and TS 6.0 compatibility

v2.6.8 - ESLint 10 stabilization and TS 6.0 compatibility #291

Workflow file for this run

name: Build and Push Docker Images
on:
push:
tags: ["v*"]
pull_request:
branches: [main]
env:
REGISTRY: docker.io
IMAGE_NAME: writenotenow/d1-manager
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
permissions:
contents: read
packages: write
security-events: write # For security scanning
pull-requests: write # For PR comments
id-token: write # For supply chain attestations
attestations: write # For generating attestations
jobs:
# Prerequisite: Lint and Build Verification
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24.x"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npm run lint
- name: Build frontend
run: npm run build
- name: Build worker
run: npx wrangler deploy --dry-run
# Prerequisite: CodeQL Security Analysis
codeql:
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: javascript-typescript
- name: Autobuild
uses: github/codeql-action/autobuild@v4
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
upload: always
# Build each platform on native architecture (avoids QEMU emulation issues)
# Images are built but NOT pushed yet - push happens after security-scan passes
build-platform:
needs: [lint, codeql]
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
runner: ubuntu-latest
- platform: linux/arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
id-token: write
attestations: write
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v4
continue-on-error: true
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Read version from package.json
id: version
run: |
VERSION=$(jq -r '.version // empty' package.json || echo "")
if [ -z "$VERSION" ] || [ "$VERSION" = "null" ]; then
echo "Error: Failed to extract version from package.json" >&2
exit 1
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Detected version: $VERSION"
- name: Extract metadata
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: |
latest=false
suffix=-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}
tags: |
type=sha,prefix=sha-,format=short
- name: Build platform image (no push - security scan first)
id: build
uses: docker/build-push-action@v7
with:
context: .
file: Dockerfile
platforms: ${{ matrix.platform }}
push: false
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=${{ matrix.platform }}
cache-to: type=gha,scope=${{ matrix.platform }},mode=max
provenance: mode=max
sbom: true
# Security scan with Docker Scout (blocks on critical/high fixable vulns)
security-scan:
runs-on: ubuntu-latest
needs: build-platform
if: github.event_name != 'pull_request'
permissions:
contents: read
security-events: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build image for scanning
uses: docker/build-push-action@v7
with:
context: .
file: Dockerfile
platforms: linux/amd64
push: false
load: true
tags: local-scan:latest
cache-from: type=gha,scope=linux/amd64
- name: Docker Scout CVE Scan
uses: docker/scout-action@v1
with:
command: cves
image: local://local-scan:latest
exit-code: true
only-severities: critical,high
only-fixed: true
sarif-file: scout-results.sarif
- name: Upload Scout results to GitHub Security
uses: github/codeql-action/upload-sarif@v4
if: always()
with:
sarif_file: scout-results.sarif
# Push platform images AFTER security scan passes
# This job gates Docker Hub publishing on security verification
push-platform:
needs: [build-platform, security-scan]
if: github.event_name != 'pull_request'
strategy:
fail-fast: false
matrix:
include:
- platform: linux/amd64
runner: ubuntu-latest
- platform: linux/arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
id-token: write
attestations: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: |
latest=false
suffix=-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}
tags: |
type=sha,prefix=sha-,format=short
- name: Build and push platform image (from cache)
id: build
uses: docker/build-push-action@v7
with:
context: .
file: Dockerfile
platforms: ${{ matrix.platform }}
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=${{ matrix.platform }}
provenance: mode=max
sbom: true
- name: Export digest
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v6
with:
name: digests-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
# Merge platform images into multi-arch manifest
merge-and-push:
runs-on: ubuntu-latest
needs: [push-platform]
if: github.event_name != 'pull_request'
permissions:
contents: read
packages: write
id-token: write
attestations: write
deployments: write
environment:
name: ${{ startsWith(github.ref, 'refs/tags/v') && 'production' || '' }}
url: https://hub.docker.com/r/writenotenow/d1-manager
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Download digests
uses: actions/download-artifact@v7
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Read version
id: version
run: |
VERSION=$(jq -r '.version // empty' package.json || echo "")
if [ -z "$VERSION" ] || [ "$VERSION" = "null" ]; then
echo "Error: Failed to extract version from package.json" >&2
exit 1
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Extract metadata for manifest
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: |
latest=auto
tags: |
type=semver,pattern=v{{version}}
type=raw,value=v${{ steps.version.outputs.version }},enable=${{ github.event_name != 'pull_request' }}
type=raw,value=latest,enable=${{ github.event_name != 'pull_request' }}
type=sha,prefix=sha-,format=short
- name: Create and push manifest
working-directory: /tmp/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
- name: Inspect manifest
run: |
docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
# Update Docker Hub description
- name: Update Docker Hub Description
if: startsWith(github.ref, 'refs/tags/v')
uses: peter-evans/dockerhub-description@v5
continue-on-error: true
timeout-minutes: 5
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
repository: ${{ env.IMAGE_NAME }}
readme-filepath: ./DOCKER_README.md
short-description: "Cloudflare D1 Manager with SQL Console, Drizzle, Visual Schema/ER tools, Scheduled Backups."
- name: Deployment Summary
if: startsWith(github.ref, 'refs/tags/v')
run: |
echo "✅ Successfully published Docker images to production"
echo "🐳 Registry: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"
echo "🏷️ Tags: ${{ steps.meta.outputs.tags }}"
echo "📝 Commit: ${{ github.sha }}"
echo "👤 Published by: ${{ github.actor }}"