Some enhancements to the pipeline... Liking woodpecker...

This commit is contained in:
2026-01-30 23:43:06 -03:00
parent 0c34d37110
commit 8d688291df
5 changed files with 122 additions and 95 deletions

View File

@@ -1,85 +1,85 @@
# Deploy pipeline: lint, test, build, then Docker image → registry → Portainer webhook. # Deploy pipeline: lint, test, build, then Docker image → registry → Portainer webhook.
# Runs on push to main, tag, or manual run. # 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: when:
branch: main branch: main
event: [push, tag, manual] event: [push, tag, manual]
steps: steps:
- name: build-and-test - name: build-and-test
image: node:20-alpine image: node:20-alpine
commands: commands:
- corepack enable && corepack prepare pnpm@10.28.2 --activate - corepack enable && corepack prepare pnpm@10.28.2 --activate
- pnpm install --frozen-lockfile || pnpm install - pnpm install --frozen-lockfile || pnpm install
- pnpm run lint - pnpm run lint
- pnpm run lint:css - pnpm run lint:css
- pnpm run build - pnpm run build
- pnpm test - pnpm test
- name: build - name: build
image: docker:latest image: docker:latest
environment: environment:
REGISTRY_REPO: git.mifi.dev/mifi-ventures/landing REGISTRY_REPO: git.mifi.dev/mifi-ventures/landing
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
commands: commands:
- set -e - set -e
- echo "=== Building Docker image ===" - echo "=== Building Docker image ==="
- 'echo "Commit SHA: ${CI_COMMIT_SHA:0:8}"' - 'echo "Commit SHA: ${CI_COMMIT_SHA:0:8}"'
- 'echo "Registry repo: $REGISTRY_REPO"' - 'echo "Registry repo: $REGISTRY_REPO"'
- | - |
docker build \ docker build \
--tag $REGISTRY_REPO:${CI_COMMIT_SHA} \ --tag $REGISTRY_REPO:${CI_COMMIT_SHA} \
--tag $REGISTRY_REPO:latest \ --tag $REGISTRY_REPO:latest \
--label "git.commit=${CI_COMMIT_SHA}" \ --label "git.commit=${CI_COMMIT_SHA}" \
--label "git.branch=${CI_COMMIT_BRANCH}" \ --label "git.branch=${CI_COMMIT_BRANCH}" \
. .
- echo "✓ Docker image built successfully" - echo "✓ Docker image built successfully"
depends_on: depends_on:
- build-and-test - build-and-test
- name: push - name: push
image: docker:latest image: docker:latest
environment: environment:
REGISTRY_URL: git.mifi.dev REGISTRY_URL: git.mifi.dev
REGISTRY_REPO: git.mifi.dev/mifi-ventures/landing REGISTRY_REPO: git.mifi.dev/mifi-ventures/landing
REGISTRY_USERNAME: REGISTRY_USERNAME:
from_secret: registry_username from_secret: registry_username
REGISTRY_PASSWORD: REGISTRY_PASSWORD:
from_secret: registry_password from_secret: registry_password
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
commands: commands:
- set -e - set -e
- echo "=== Pushing to registry ===" - echo "=== Pushing to registry ==="
- 'echo "Registry: $REGISTRY_URL"' - 'echo "Registry: $REGISTRY_URL"'
- 'echo "Repository: $REGISTRY_REPO"' - 'echo "Repository: $REGISTRY_REPO"'
- | - |
echo "$REGISTRY_PASSWORD" | docker login "$REGISTRY_URL" \ echo "$REGISTRY_PASSWORD" | docker login "$REGISTRY_URL" \
-u "$REGISTRY_USERNAME" \ -u "$REGISTRY_USERNAME" \
--password-stdin --password-stdin
- docker push $REGISTRY_REPO:${CI_COMMIT_SHA} - docker push $REGISTRY_REPO:${CI_COMMIT_SHA}
- docker push $REGISTRY_REPO:latest - docker push $REGISTRY_REPO:latest
- echo "✓ Images pushed successfully" - echo "✓ Images pushed successfully"
depends_on: depends_on:
- build - build
- name: deploy - name: deploy
image: curlimages/curl:latest image: curlimages/curl:latest
environment: environment:
PORTAINER_WEBHOOK_URL: PORTAINER_WEBHOOK_URL:
from_secret: portainer_webhook_url from_secret: portainer_webhook_url
commands: commands:
- set -e - set -e
- echo "=== Triggering Portainer stack redeploy ===" - echo "=== Triggering Portainer stack redeploy ==="
- | - |
resp=$(curl -s -w "\n%{http_code}" -X POST "$PORTAINER_WEBHOOK_URL") resp=$(curl -s -w "\n%{http_code}" -X POST "$PORTAINER_WEBHOOK_URL")
body=$(echo "$resp" | head -n -1) body=$(echo "$resp" | head -n -1)
code=$(echo "$resp" | tail -n 1) code=$(echo "$resp" | tail -n 1)
if [ "$code" != "200" ] && [ "$code" != "204" ]; then if [ "$code" != "200" ] && [ "$code" != "204" ]; then
echo "Webhook failed (HTTP $code): $body" echo "Webhook failed (HTTP $code): $body"
exit 1 exit 1
fi fi
echo "✓ Portainer redeploy triggered (HTTP $code)" echo "✓ Portainer redeploy triggered (HTTP $code)"
depends_on: depends_on:
- push - push

View 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

View File

@@ -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

View File

@@ -104,7 +104,7 @@ mifi-ventures-landing/
│ ├── devcontainer.json # Dev container config (extensions) │ ├── devcontainer.json # Dev container config (extensions)
│ └── Dockerfile # Dev container image (Node) │ └── Dockerfile # Dev container image (Node)
├── .woodpecker/ # CI/CD pipelines (see below) ├── .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 │ └── deploy.yaml # main: lint, test, build, Docker, push, webhook
├── Dockerfile # Production container (nginx:alpine) ├── Dockerfile # Production container (nginx:alpine)
├── nginx.conf # nginx web server configuration ├── nginx.conf # nginx web server configuration
@@ -140,7 +140,7 @@ mifi-ventures-landing/
### Pipeline Overview ### 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. - **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: - **Push to main** (or tag / manual run): Runs the same lint, test, and build, then:

View File

@@ -2,6 +2,7 @@ import js from '@eslint/js';
import tseslint from 'typescript-eslint'; import tseslint from 'typescript-eslint';
import svelte from 'eslint-plugin-svelte'; import svelte from 'eslint-plugin-svelte';
import prettier from 'eslint-config-prettier'; import prettier from 'eslint-config-prettier';
import svelteConfig from './svelte.config.js';
export default [ export default [
{ {
@@ -19,6 +20,17 @@ export default [
...tseslint.configs.recommended, ...tseslint.configs.recommended,
...svelte.configs['flat/recommended'], ...svelte.configs['flat/recommended'],
prettier, prettier,
{
files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],
languageOptions: {
parserOptions: {
parser: tseslint.parser,
projectService: true,
extraFileExtensions: ['.svelte'],
svelteConfig
}
}
},
{ {
files: ['**/*.mjs', 'build.mjs'], files: ['**/*.mjs', 'build.mjs'],
languageOptions: { globals: { console: 'readonly', process: 'readonly' } } languageOptions: { globals: { console: 'readonly', process: 'readonly' } }