The Svelte 5 SSG Migration #1
@@ -1,85 +1,85 @@
|
||||
# Deploy pipeline: lint, test, build, then Docker image → registry → Portainer webhook.
|
||||
# Runs on push to main, tag, or manual run.
|
||||
# See pr.yaml for PR-only (lint + test + build).
|
||||
# See lint-and-build.yaml for PR-only (lint + test + build).
|
||||
when:
|
||||
branch: main
|
||||
event: [push, tag, manual]
|
||||
branch: main
|
||||
event: [push, tag, manual]
|
||||
|
||||
steps:
|
||||
- name: build-and-test
|
||||
image: node:20-alpine
|
||||
commands:
|
||||
- corepack enable && corepack prepare pnpm@10.28.2 --activate
|
||||
- pnpm install --frozen-lockfile || pnpm install
|
||||
- pnpm run lint
|
||||
- pnpm run lint:css
|
||||
- pnpm run build
|
||||
- pnpm test
|
||||
- name: build-and-test
|
||||
image: node:20-alpine
|
||||
commands:
|
||||
- corepack enable && corepack prepare pnpm@10.28.2 --activate
|
||||
- pnpm install --frozen-lockfile || pnpm install
|
||||
- pnpm run lint
|
||||
- pnpm run lint:css
|
||||
- pnpm run build
|
||||
- pnpm test
|
||||
|
||||
- name: build
|
||||
image: docker:latest
|
||||
environment:
|
||||
REGISTRY_REPO: git.mifi.dev/mifi-ventures/landing
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
commands:
|
||||
- set -e
|
||||
- echo "=== Building Docker image ==="
|
||||
- 'echo "Commit SHA: ${CI_COMMIT_SHA:0:8}"'
|
||||
- 'echo "Registry repo: $REGISTRY_REPO"'
|
||||
- |
|
||||
docker build \
|
||||
--tag $REGISTRY_REPO:${CI_COMMIT_SHA} \
|
||||
--tag $REGISTRY_REPO:latest \
|
||||
--label "git.commit=${CI_COMMIT_SHA}" \
|
||||
--label "git.branch=${CI_COMMIT_BRANCH}" \
|
||||
.
|
||||
- echo "✓ Docker image built successfully"
|
||||
depends_on:
|
||||
- build-and-test
|
||||
- name: build
|
||||
image: docker:latest
|
||||
environment:
|
||||
REGISTRY_REPO: git.mifi.dev/mifi-ventures/landing
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
commands:
|
||||
- set -e
|
||||
- echo "=== Building Docker image ==="
|
||||
- 'echo "Commit SHA: ${CI_COMMIT_SHA:0:8}"'
|
||||
- 'echo "Registry repo: $REGISTRY_REPO"'
|
||||
- |
|
||||
docker build \
|
||||
--tag $REGISTRY_REPO:${CI_COMMIT_SHA} \
|
||||
--tag $REGISTRY_REPO:latest \
|
||||
--label "git.commit=${CI_COMMIT_SHA}" \
|
||||
--label "git.branch=${CI_COMMIT_BRANCH}" \
|
||||
.
|
||||
- echo "✓ Docker image built successfully"
|
||||
depends_on:
|
||||
- build-and-test
|
||||
|
||||
- name: push
|
||||
image: docker:latest
|
||||
environment:
|
||||
REGISTRY_URL: git.mifi.dev
|
||||
REGISTRY_REPO: git.mifi.dev/mifi-ventures/landing
|
||||
REGISTRY_USERNAME:
|
||||
from_secret: registry_username
|
||||
REGISTRY_PASSWORD:
|
||||
from_secret: registry_password
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
commands:
|
||||
- set -e
|
||||
- echo "=== Pushing to registry ==="
|
||||
- 'echo "Registry: $REGISTRY_URL"'
|
||||
- 'echo "Repository: $REGISTRY_REPO"'
|
||||
- |
|
||||
echo "$REGISTRY_PASSWORD" | docker login "$REGISTRY_URL" \
|
||||
-u "$REGISTRY_USERNAME" \
|
||||
--password-stdin
|
||||
- docker push $REGISTRY_REPO:${CI_COMMIT_SHA}
|
||||
- docker push $REGISTRY_REPO:latest
|
||||
- echo "✓ Images pushed successfully"
|
||||
depends_on:
|
||||
- build
|
||||
- name: push
|
||||
image: docker:latest
|
||||
environment:
|
||||
REGISTRY_URL: git.mifi.dev
|
||||
REGISTRY_REPO: git.mifi.dev/mifi-ventures/landing
|
||||
REGISTRY_USERNAME:
|
||||
from_secret: registry_username
|
||||
REGISTRY_PASSWORD:
|
||||
from_secret: registry_password
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
commands:
|
||||
- set -e
|
||||
- echo "=== Pushing to registry ==="
|
||||
- 'echo "Registry: $REGISTRY_URL"'
|
||||
- 'echo "Repository: $REGISTRY_REPO"'
|
||||
- |
|
||||
echo "$REGISTRY_PASSWORD" | docker login "$REGISTRY_URL" \
|
||||
-u "$REGISTRY_USERNAME" \
|
||||
--password-stdin
|
||||
- docker push $REGISTRY_REPO:${CI_COMMIT_SHA}
|
||||
- docker push $REGISTRY_REPO:latest
|
||||
- echo "✓ Images pushed successfully"
|
||||
depends_on:
|
||||
- build
|
||||
|
||||
- name: deploy
|
||||
image: curlimages/curl:latest
|
||||
environment:
|
||||
PORTAINER_WEBHOOK_URL:
|
||||
from_secret: portainer_webhook_url
|
||||
commands:
|
||||
- set -e
|
||||
- echo "=== Triggering Portainer stack redeploy ==="
|
||||
- |
|
||||
resp=$(curl -s -w "\n%{http_code}" -X POST "$PORTAINER_WEBHOOK_URL")
|
||||
body=$(echo "$resp" | head -n -1)
|
||||
code=$(echo "$resp" | tail -n 1)
|
||||
if [ "$code" != "200" ] && [ "$code" != "204" ]; then
|
||||
echo "Webhook failed (HTTP $code): $body"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ Portainer redeploy triggered (HTTP $code)"
|
||||
depends_on:
|
||||
- push
|
||||
- name: deploy
|
||||
image: curlimages/curl:latest
|
||||
environment:
|
||||
PORTAINER_WEBHOOK_URL:
|
||||
from_secret: portainer_webhook_url
|
||||
commands:
|
||||
- set -e
|
||||
- echo "=== Triggering Portainer stack redeploy ==="
|
||||
- |
|
||||
resp=$(curl -s -w "\n%{http_code}" -X POST "$PORTAINER_WEBHOOK_URL")
|
||||
body=$(echo "$resp" | head -n -1)
|
||||
code=$(echo "$resp" | tail -n 1)
|
||||
if [ "$code" != "200" ] && [ "$code" != "204" ]; then
|
||||
echo "Webhook failed (HTTP $code): $body"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ Portainer redeploy triggered (HTTP $code)"
|
||||
depends_on:
|
||||
- push
|
||||
|
||||
31
.woodpecker/lint-and-build.yaml
Normal file
31
.woodpecker/lint-and-build.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
# PR pipeline: lint, build, test on the branch (separate steps, shared workspace).
|
||||
# Runs when a pull request is opened or updated.
|
||||
# Does not build Docker image or deploy.
|
||||
when:
|
||||
event: pull_request
|
||||
|
||||
steps:
|
||||
- name: install
|
||||
image: node:20-alpine
|
||||
commands:
|
||||
- corepack enable && corepack prepare pnpm@10.28.2 --activate
|
||||
- pnpm install --frozen-lockfile || pnpm install
|
||||
|
||||
- name: lint
|
||||
image: node:20-alpine
|
||||
commands:
|
||||
- corepack enable && corepack prepare pnpm@10.28.2 --activate
|
||||
- pnpm run lint
|
||||
- pnpm run lint:css
|
||||
|
||||
- name: build
|
||||
image: node:20-alpine
|
||||
commands:
|
||||
- corepack enable && corepack prepare pnpm@10.28.2 --activate
|
||||
- pnpm run build
|
||||
|
||||
- name: test
|
||||
image: node:20-alpine
|
||||
commands:
|
||||
- corepack enable && corepack prepare pnpm@10.28.2 --activate
|
||||
- pnpm test
|
||||
@@ -1,16 +0,0 @@
|
||||
# PR pipeline: lint, test, and test build on the branch.
|
||||
# Runs when a pull request is opened or updated.
|
||||
# Does not build Docker image or deploy.
|
||||
when:
|
||||
event: pull_request
|
||||
|
||||
steps:
|
||||
- name: lint-and-build
|
||||
image: node:20-alpine
|
||||
commands:
|
||||
- corepack enable && corepack prepare pnpm@10.28.2 --activate
|
||||
- pnpm install --frozen-lockfile || pnpm install
|
||||
- pnpm run lint
|
||||
- pnpm run lint:css
|
||||
- pnpm run build
|
||||
- pnpm test
|
||||
@@ -104,7 +104,7 @@ mifi-ventures-landing/
|
||||
│ ├── devcontainer.json # Dev container config (extensions)
|
||||
│ └── Dockerfile # Dev container image (Node)
|
||||
├── .woodpecker/ # CI/CD pipelines (see below)
|
||||
│ ├── pr.yaml # PR: lint, test, build (no deploy)
|
||||
│ ├── lint-and-build.yaml # PR: lint, test, build (no deploy)
|
||||
│ └── deploy.yaml # main: lint, test, build, Docker, push, webhook
|
||||
├── Dockerfile # Production container (nginx:alpine)
|
||||
├── nginx.conf # nginx web server configuration
|
||||
@@ -140,7 +140,7 @@ mifi-ventures-landing/
|
||||
|
||||
### Pipeline Overview
|
||||
|
||||
Woodpecker uses two workflows (`.woodpecker/pr.yaml` and `.woodpecker/deploy.yaml`):
|
||||
Woodpecker uses two workflows (`.woodpecker/lint-and-build.yaml` and `.woodpecker/deploy.yaml`):
|
||||
|
||||
- **Pull requests**: Opening or updating a PR runs **lint** (ESLint + Stylelint), **tests** (Vitest), and a **test build** (SvelteKit + Critters) on the branch. No Docker image or deploy.
|
||||
- **Push to main** (or tag / manual run): Runs the same lint, test, and build, then:
|
||||
|
||||
@@ -2,6 +2,7 @@ import js from '@eslint/js';
|
||||
import tseslint from 'typescript-eslint';
|
||||
import svelte from 'eslint-plugin-svelte';
|
||||
import prettier from 'eslint-config-prettier';
|
||||
import svelteConfig from './svelte.config.js';
|
||||
|
||||
export default [
|
||||
{
|
||||
@@ -19,6 +20,17 @@ export default [
|
||||
...tseslint.configs.recommended,
|
||||
...svelte.configs['flat/recommended'],
|
||||
prettier,
|
||||
{
|
||||
files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
parser: tseslint.parser,
|
||||
projectService: true,
|
||||
extraFileExtensions: ['.svelte'],
|
||||
svelteConfig
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['**/*.mjs', 'build.mjs'],
|
||||
languageOptions: { globals: { console: 'readonly', process: 'readonly' } }
|
||||
|
||||
Reference in New Issue
Block a user