diff --git a/.woodpecker/deploy.yaml b/.woodpecker/deploy.yaml index 70c9c40..21388b5 100644 --- a/.woodpecker/deploy.yaml +++ b/.woodpecker/deploy.yaml @@ -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 diff --git a/.woodpecker/lint-and-build.yaml b/.woodpecker/lint-and-build.yaml new file mode 100644 index 0000000..a510f23 --- /dev/null +++ b/.woodpecker/lint-and-build.yaml @@ -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 diff --git a/.woodpecker/pr.yaml b/.woodpecker/pr.yaml deleted file mode 100644 index 63d0fba..0000000 --- a/.woodpecker/pr.yaml +++ /dev/null @@ -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 diff --git a/README.md b/README.md index 4fb8fb3..d4dfaf2 100644 --- a/README.md +++ b/README.md @@ -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: diff --git a/eslint.config.js b/eslint.config.js index 64ee227..bfe3741 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -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' } }