diff --git a/.github/badges/master-payload-size.json b/.github/badges/master-payload-size.json deleted file mode 100644 index 88c3a4a..0000000 --- a/.github/badges/master-payload-size.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "schemaVersion": 1, - "label": "master payload", - "message": "12.0 MiB", - "color": "yellow" -} diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index b398a66..c3921de 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -44,6 +44,19 @@ jobs: echo "IMAGE=${REGISTRY}/${OWNER}/${IMAGE_NAME}" >> "$GITHUB_ENV" echo "Image namespace: ${REGISTRY}/${OWNER}/${IMAGE_NAME}" + - name: Compute build info + id: build_info + run: | + { + echo "created=$(date -u +%Y-%m-%dT%H:%M:%SZ)" + echo "source=https://github.com/${GITHUB_REPOSITORY}" + echo "branch=${GITHUB_REF_NAME}" + echo "run_url=https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" + echo "author<> "$GITHUB_OUTPUT" + - name: Docker metadata id: meta uses: docker/metadata-action@v6 @@ -68,6 +81,17 @@ jobs: ${{ env.IMAGE }}:ci ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + build-args: | + BUILD_DATE=${{ steps.build_info.outputs.created }} + VCS_REF=${{ github.sha }} + VCS_URL=${{ steps.build_info.outputs.source }} + SOURCE_BRANCH=${{ steps.build_info.outputs.branch }} + IMAGE_NAME=${{ env.IMAGE }} + GITHUB_RUN_ID=${{ github.run_id }} + GITHUB_RUN_ATTEMPT=${{ github.run_attempt }} + GITHUB_RUN_URL=${{ steps.build_info.outputs.run_url }} + GITHUB_ACTOR=${{ github.actor }} + COMMIT_AUTHOR=${{ steps.build_info.outputs.author }} cache-from: type=gha cache-to: type=gha,mode=max,ignore-error=true @@ -124,6 +148,19 @@ jobs: echo "IMAGE=${REGISTRY}/${OWNER}/${IMAGE_NAME}" >> "$GITHUB_ENV" echo "Image namespace: ${REGISTRY}/${OWNER}/${IMAGE_NAME}" + - name: Compute build info + id: build_info + run: | + { + echo "created=$(date -u +%Y-%m-%dT%H:%M:%SZ)" + echo "source=https://github.com/${GITHUB_REPOSITORY}" + echo "branch=${GITHUB_REF_NAME}" + echo "run_url=https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" + echo "author<> "$GITHUB_OUTPUT" + - name: Docker metadata id: meta uses: docker/metadata-action@v6 @@ -165,5 +202,67 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + build-args: | + BUILD_DATE=${{ steps.build_info.outputs.created }} + VCS_REF=${{ github.sha }} + VCS_URL=${{ steps.build_info.outputs.source }} + SOURCE_BRANCH=${{ steps.build_info.outputs.branch }} + IMAGE_NAME=${{ env.IMAGE }} + GITHUB_RUN_ID=${{ github.run_id }} + GITHUB_RUN_ATTEMPT=${{ github.run_attempt }} + GITHUB_RUN_URL=${{ steps.build_info.outputs.run_url }} + GITHUB_ACTOR=${{ github.actor }} + COMMIT_AUTHOR=${{ steps.build_info.outputs.author }} cache-from: type=gha cache-to: type=gha,mode=max,ignore-error=true + + update-size-badge: + needs: build + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + runs-on: ubuntu-latest + continue-on-error: true + permissions: + contents: write + + steps: + - name: Configure Git default branch + run: git config --global init.defaultBranch master + + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Generate badge data + run: BADGE_PATH=tmp/master-payload-size.json bash scripts/update-size-badge.sh + + - name: Publish badge data + run: | + set -euo pipefail + badge_branch="size-badge-data" + badge_file="tmp/master-payload-size.json" + worktree="$(mktemp -d)" + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + if git ls-remote --exit-code --heads origin "$badge_branch" >/dev/null 2>&1; then + git fetch origin "$badge_branch" + git worktree add "$worktree" "origin/$badge_branch" + git -C "$worktree" switch -c "$badge_branch" + else + git worktree add --detach "$worktree" + git -C "$worktree" switch --orphan "$badge_branch" + git -C "$worktree" rm -rf . >/dev/null 2>&1 || true + fi + + cp "$badge_file" "$worktree/master-payload-size.json" + git -C "$worktree" add master-payload-size.json + + if git -C "$worktree" diff --cached --quiet; then + echo "Badge data unchanged" + exit 0 + fi + + git -C "$worktree" commit -m "Update master payload badge" + git -C "$worktree" push origin "HEAD:$badge_branch" diff --git a/Caddyfile.site b/Caddyfile.site index 6bfe3a6..b4898dd 100644 --- a/Caddyfile.site +++ b/Caddyfile.site @@ -2,6 +2,7 @@ root * /srv encode zstd gzip respond /healthz 200 + header /build-info.json Cache-Control "no-store" header /_next/static/* Cache-Control "public, max-age=31536000, immutable" header /optimized/* Cache-Control "public, max-age=604800" header /partners/* Cache-Control "public, max-age=604800" diff --git a/Dockerfile b/Dockerfile index c809b1e..560f8d0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,11 +16,50 @@ RUN npm run build FROM caddy:2.9-alpine AS runner WORKDIR /srv +ARG BUILD_DATE="unknown" +ARG VCS_REF="unknown" +ARG VCS_URL="https://github.com/Devsh-Graphics-Programming/MainWebsite" +ARG SOURCE_BRANCH="unknown" +ARG IMAGE_NAME="www-website" +ARG GITHUB_RUN_ID="unknown" +ARG GITHUB_RUN_ATTEMPT="unknown" +ARG GITHUB_RUN_URL="unknown" +ARG GITHUB_ACTOR="unknown" +ARG COMMIT_AUTHOR="unknown" + +LABEL org.opencontainers.image.title="DevSH Graphics Programming Website" \ + org.opencontainers.image.description="Static DevSH website served by Caddy" \ + org.opencontainers.image.url="https://www.devsh.eu" \ + org.opencontainers.image.source="${VCS_URL}" \ + org.opencontainers.image.revision="${VCS_REF}" \ + org.opencontainers.image.created="${BUILD_DATE}" \ + org.opencontainers.image.authors="${COMMIT_AUTHOR}" + RUN addgroup -S caddy && adduser -S caddy -G caddy COPY --from=build --chown=caddy:caddy /app/out ./ COPY --chown=caddy:caddy Caddyfile.site /etc/caddy/Caddyfile +RUN set -eu; \ + json_escape() { printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'; }; \ + { \ + printf '{\n'; \ + printf ' "schemaVersion": 1,\n'; \ + printf ' "image": "%s",\n' "$(json_escape "$IMAGE_NAME")"; \ + printf ' "source": "%s",\n' "$(json_escape "$VCS_URL")"; \ + printf ' "revision": "%s",\n' "$(json_escape "$VCS_REF")"; \ + printf ' "branch": "%s",\n' "$(json_escape "$SOURCE_BRANCH")"; \ + printf ' "created": "%s",\n' "$(json_escape "$BUILD_DATE")"; \ + printf ' "commitAuthor": "%s",\n' "$(json_escape "$COMMIT_AUTHOR")"; \ + printf ' "builder": {\n'; \ + printf ' "actor": "%s",\n' "$(json_escape "$GITHUB_ACTOR")"; \ + printf ' "runId": "%s",\n' "$(json_escape "$GITHUB_RUN_ID")"; \ + printf ' "runAttempt": "%s",\n' "$(json_escape "$GITHUB_RUN_ATTEMPT")"; \ + printf ' "runUrl": "%s"\n' "$(json_escape "$GITHUB_RUN_URL")"; \ + printf ' }\n'; \ + printf '}\n'; \ + } > /srv/build-info.json + EXPOSE 3000 USER caddy ENTRYPOINT ["caddy", "run", "--config=/etc/caddy/Caddyfile"] diff --git a/README.md b/README.md index 1504b30..21d7cca 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Build Status - Master payload size + Master payload size Join our Discord @@ -24,7 +24,7 @@ This repo is a Next.js app used to generate a static site. The final production ## Repository size budget - CI fails if the tracked tree exceeds `10 MiB`, `public/` exceeds `8 MiB`, any tracked blob exceeds `1 MiB`, or HEAD Git blob payloads exceed `15 MiB`. -- Run `scripts/check-size-budget.sh` locally before adding new media. If the badge changes, commit the updated `.github/badges/master-payload-size.json`. +- Run `scripts/check-size-budget.sh` locally before adding new media. The README badge is informational and is updated outside the size gate. ## Runtime filesystem layout - The image is read-only, but Caddy still needs tiny writable slots for TLS cache/autosave/lock files. diff --git a/app/components/Footer.tsx b/app/components/Footer.tsx index 00a325d..26ec446 100644 --- a/app/components/Footer.tsx +++ b/app/components/Footer.tsx @@ -4,6 +4,12 @@ export default function footer() { return (
+ + build info +
) -} \ No newline at end of file +} diff --git a/app/components/Partners.tsx b/app/components/Partners.tsx index 7557c34..b0d78f0 100644 --- a/app/components/Partners.tsx +++ b/app/components/Partners.tsx @@ -12,8 +12,8 @@ export type Partner = { const partners: Partner[] = [ { name: "Applications in CADD", initials: "AC", logo: "/partners/appscadd.png", url: "https://appsincadd.co.uk/" }, { name: "Synera", initials: "SY", logo: "/partners/synera.png", url: "https://www.synera.io/", logoTone: "invert" }, - { name: "Ditt", initials: "DT", logo: "/partners/ditt.png", url: "https://www.ditt.nl/" }, - { name: "Imverse", initials: "IM", logo: "/partners/imverse.png", url: "https://www.imverse.ch/" }, + { name: "Ditt Officemakers", initials: "DT", logo: "/partners/ditt.png", url: "https://www.ditt.nl/" }, + { name: "Imverse", initials: "IM", logo: "/partners/imverse.png", url: "https://www.imverse.com/" }, { name: "Wild Software Inc", initials: "WI", logo: "/partners/wild.jpg", url: "https://factionsvr.com/" }, { name: "RELEX Solutions", initials: "RX", logo: null, url: "https://relexsolutions.com/" }, ]; diff --git a/app/components/ProjectsSection.tsx b/app/components/ProjectsSection.tsx index 5e396fa..9b981da 100644 --- a/app/components/ProjectsSection.tsx +++ b/app/components/ProjectsSection.tsx @@ -25,7 +25,7 @@ type Project = { const projects: Project[] = [ { slug: "ditt", - company: "Ditt", + company: "Ditt Officemakers", url: "https://www.ditt.nl/", title: "Interactive GPU Path Tracer", summary: "Real-time and offline rendering work for interior design workflows using OpenCL, OptiX, Mitsuba and Vulkan.", @@ -87,7 +87,7 @@ const projects: Project[] = [ { slug: "imverse", company: "Imverse", - url: "https://www.imverse.ch/", + url: "https://www.imverse.com/", title: "GPGPU Computer Vision", summary: "Computer vision acceleration work for real-time volumetric capture and RGB+D processing.", bullets: [ diff --git a/app/components/TestimonialsSection.tsx b/app/components/TestimonialsSection.tsx index f1cebcc..9a63ea3 100644 --- a/app/components/TestimonialsSection.tsx +++ b/app/components/TestimonialsSection.tsx @@ -22,7 +22,7 @@ const testimonials: Testimonial[] = [ }, { name: "Yoran Bosman", - role: "Senior Software Architect", + role: "Partner & Software Architect", profilePicture: "/testimonials/yoran.jpg", companyIcon: "/partners/ditt.png", testimonial: diff --git a/app/services/page.tsx b/app/services/page.tsx index 5340835..72cf809 100644 --- a/app/services/page.tsx +++ b/app/services/page.tsx @@ -118,7 +118,7 @@ export default function Page() {