Compare commits

...

5 Commits

Author SHA1 Message Date
b1859c15ce fix(ci): Remove Docker BuildKit cache export to avoid Gitea artifact server timeout
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 9s
Build & Deploy / 🧪 QA (push) Successful in 53s
Build & Deploy / 🏗️ Build (push) Successful in 2m40s
Build & Deploy / 🚀 Deploy (push) Successful in 28s
Build & Deploy / 🧪 Smoke Test (push) Has been skipped
Build & Deploy / ⚡ Lighthouse (push) Has been skipped
Build & Deploy / ♿ WCAG (push) Has been skipped
Build & Deploy / 🛡️ Quality Gates (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-02-23 11:26:53 +01:00
6085cc05dc fix(ui): Add missing draw-stroke keyframes and restore Tailwind v4 backward compatibility with tailwind.config.cjs
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 11s
Build & Deploy / 🧪 QA (push) Successful in 1m33s
Build & Deploy / 🏗️ Build (push) Failing after 8m41s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🧪 Smoke Test (push) Has been skipped
Build & Deploy / ⚡ Lighthouse (push) Has been skipped
Build & Deploy / ♿ WCAG (push) Has been skipped
Build & Deploy / 🛡️ Quality Gates (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
2026-02-23 02:56:46 +01:00
bcf2d60da6 fix(ci): Strict turbo inputs and skip slow post-deploy QA for tags
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 9s
Build & Deploy / 🧪 QA (push) Successful in 3m26s
Build & Deploy / 🏗️ Build (push) Successful in 4m5s
Build & Deploy / 🚀 Deploy (push) Successful in 36s
Build & Deploy / 🧪 Smoke Test (push) Successful in 52s
Build & Deploy / 🛡️ Quality Gates (push) Successful in 1m42s
Build & Deploy / 🔔 Notify (push) Has been cancelled
Build & Deploy / ♿ WCAG (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
2026-02-23 02:44:58 +01:00
f4fdb89ba4 fix(ci): Re-enable QA for tags and use global Turborepo cache key to allow hits across branches/tags
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 19s
Build & Deploy / 🏗️ Build (push) Has been cancelled
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / ♿ WCAG (push) Has been cancelled
Build & Deploy / 🛡️ Quality Gates (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
Build & Deploy / 🧪 QA (push) Has been cancelled
2026-02-23 02:39:11 +01:00
9de3931e33 feat: Implement imgproxy health check with fallback redirection for image requests when the service is down.
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 1m12s
Build & Deploy / 🧪 QA (push) Successful in 1m56s
Build & Deploy / 🚀 Deploy (push) Blocked by required conditions
Build & Deploy / 🧪 Smoke Test (push) Blocked by required conditions
Build & Deploy / ⚡ Lighthouse (push) Blocked by required conditions
Build & Deploy / ♿ WCAG (push) Blocked by required conditions
Build & Deploy / 🛡️ Quality Gates (push) Blocked by required conditions
Build & Deploy / 🔔 Notify (push) Blocked by required conditions
Build & Deploy / 🏗️ Build (push) Has been cancelled
2026-02-23 02:35:49 +01:00
6 changed files with 85 additions and 17 deletions

View File

@@ -50,9 +50,9 @@ jobs:
uses: actions/cache@v4
with:
path: .turbo
key: ${{ runner.os }}-turbo-${{ github.ref_name }}-${{ github.sha }}
key: ${{ runner.os }}-turbo-global-${{ github.sha }}
restore-keys: |
${{ runner.os }}-turbo-${{ github.ref_name }}-
${{ runner.os }}-turbo-global-
${{ runner.os }}-turbo-
- name: 🧪 QA Checks

View File

@@ -175,9 +175,9 @@ jobs:
uses: actions/cache@v4
with:
path: .turbo
key: ${{ runner.os }}-turbo-${{ github.ref_name }}-${{ github.sha }}
key: ${{ runner.os }}-turbo-global-${{ github.sha }}
restore-keys: |
${{ runner.os }}-turbo-${{ github.ref_name }}-
${{ runner.os }}-turbo-global-
${{ runner.os }}-turbo-
- name: 🔒 Security Audit
@@ -212,8 +212,6 @@ jobs:
push: true
provenance: false
platforms: linux/arm64
cache-from: type=gha,scope=nextjs-build-${{ needs.prepare.outputs.target }}
cache-to: type=gha,mode=max,scope=nextjs-build-${{ needs.prepare.outputs.target }}
build-args: |
NEXT_PUBLIC_BASE_URL=${{ needs.prepare.outputs.next_public_url }}
NEXT_PUBLIC_TARGET=${{ needs.prepare.outputs.target }}
@@ -394,7 +392,7 @@ jobs:
name: 🧪 Smoke Test
needs: [prepare, deploy]
continue-on-error: true
if: needs.deploy.result == 'success'
if: needs.deploy.result == 'success' && github.ref_type != 'tag'
runs-on: docker
container:
image: catthehacker/ubuntu:act-latest
@@ -427,7 +425,7 @@ jobs:
name: ⚡ Lighthouse
needs: [prepare, deploy]
continue-on-error: true
if: success() && needs.prepare.outputs.target != 'skip'
if: success() && needs.prepare.outputs.target != 'skip' && github.ref_type != 'tag'
runs-on: docker
container:
image: catthehacker/ubuntu:act-latest
@@ -502,7 +500,7 @@ jobs:
name: ♿ WCAG
needs: [prepare, deploy, smoke_test]
continue-on-error: true
if: success() && needs.prepare.outputs.target != 'skip'
if: success() && needs.prepare.outputs.target != 'skip' && github.ref_type != 'tag'
runs-on: docker
container:
image: catthehacker/ubuntu:act-latest
@@ -584,7 +582,7 @@ jobs:
name: 🛡️ Quality Gates
needs: [prepare, deploy, smoke_test]
continue-on-error: true
if: success() && needs.prepare.outputs.target != 'skip'
if: success() && needs.prepare.outputs.target != 'skip' && github.ref_type != 'tag'
runs-on: docker
container:
image: catthehacker/ubuntu:act-latest

View File

@@ -41,10 +41,7 @@ CMD ["pnpm", "dev:local"]
# Build application
# Stage 3: Builder (Production)
FROM base AS builder
RUN --mount=type=cache,target=/app/.next/cache,id=nextjs-cache \
pnpm build && \
mkdir -p /app/.next-cache-tmp && \
cp -r /app/.next/cache/* /app/.next-cache-tmp/ || true
RUN pnpm build
# Stage 3: Runner
FROM registry.infra.mintel.me/mintel/runtime:v1.7.10 AS runner
@@ -63,6 +60,6 @@ ENV NODE_ENV=production
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/.next-cache-tmp ./.next/cache
COPY --from=builder --chown=nextjs:nodejs /app/.next/cache ./.next/cache
CMD ["node", "server.js"]

View File

@@ -10,10 +10,38 @@ const intlMiddleware = createMiddleware({
defaultLocale: 'en',
});
export default function middleware(request: NextRequest) {
const imgproxyStatus = { isDown: false, lastCheck: 0 };
async function isImgproxyDown() {
const now = Date.now();
if (now - imgproxyStatus.lastCheck > 60000) {
try {
const imgproxyUrl = process.env.IMGPROXY_URL || 'https://img.infra.mintel.me';
const checkUrl = imgproxyUrl.startsWith('http') ? imgproxyUrl : `https://${imgproxyUrl}`;
const res = await fetch(checkUrl, { signal: AbortSignal.timeout(2000) });
imgproxyStatus.isDown = res.status >= 500;
} catch (e) {
imgproxyStatus.isDown = true;
}
imgproxyStatus.lastCheck = now;
}
return imgproxyStatus.isDown;
}
export default async function middleware(request: NextRequest) {
const { method, url, headers } = request;
const { pathname } = request.nextUrl;
if (pathname.startsWith('/_img/')) {
if (await isImgproxyDown()) {
const originalUrl = request.nextUrl.searchParams.get('url');
if (originalUrl) {
return NextResponse.redirect(originalUrl);
}
}
return NextResponse.next();
}
// Explicit bypass for infrastructure routes to avoid locale redirects/interception
if (
pathname.startsWith('/stats') ||
@@ -97,7 +125,7 @@ export default function middleware(request: NextRequest) {
export const config = {
matcher: [
'/((?!api|_next/static|_next/image|_img|favicon.ico|manifest.webmanifest|.*\\.(?:svg|png|jpg|jpeg|gif|webp|pdf|txt|vcf|xml|webm|mp4|map)$).*)',
'/((?!api|_next/static|_next/image|favicon.ico|manifest.webmanifest|.*\\.(?:svg|png|jpg|jpeg|gif|webp|pdf|txt|vcf|xml|webm|mp4|map)$).*)',
'/(de|en)/:path*',
'/(de|en)/:path*',
],

View File

@@ -1,4 +1,5 @@
@import 'tailwindcss';
@config "../tailwind.config.cjs";
@theme {
--font-sans:
@@ -46,6 +47,18 @@
--animate-slight-fade-in-from-bottom: slight-fade-in-from-bottom 0.8s
cubic-bezier(0.16, 1, 0.3, 1) forwards;
--animate-gradient-x: gradient-x 15s ease infinite;
--animate-draw-stroke: draw-stroke 1.8s ease-in-out 0.5s forwards;
@keyframes draw-stroke {
from {
stroke-dasharray: 1;
stroke-dashoffset: 1;
}
to {
stroke-dasharray: 1;
stroke-dashoffset: 0;
}
}
@keyframes gradient-x {
0%,

View File

@@ -1,19 +1,51 @@
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": [
"pnpm-lock.yaml",
".gitea/workflows/ci.yml",
".gitea/workflows/deploy.yml"
],
"tasks": {
"lint": {
"inputs": [
"app/**/*.tsx",
"app/**/*.ts",
"components/**/*.tsx",
"components/**/*.ts",
"lib/**/*.ts",
"eslint.config.mjs"
],
"outputs": []
},
"typecheck": {
"inputs": [
"app/**/*.tsx",
"app/**/*.ts",
"components/**/*.tsx",
"components/**/*.ts",
"lib/**/*.ts",
"tsconfig.json"
],
"outputs": []
},
"test": {
"inputs": [
"app/**/*.tsx",
"app/**/*.ts",
"components/**/*.tsx",
"components/**/*.ts",
"lib/**/*.ts",
"tests/**/*.ts",
"vitest.config.mts"
],
"outputs": []
},
"check:spell": {
"inputs": ["content/**/*.{md,mdx}", "app/**/*.tsx", "components/**/*.tsx", "cspell.json"],
"outputs": []
},
"check:mdx": {
"inputs": ["content/**/*.{md,mdx}", "scripts/validate-mdx.mjs"],
"outputs": []
}
}