|
1 |
| -# This is a Semaphore configuration file for Phoenix projects using Docker |
2 |
| -# For more information about Semaphore configuration visit: |
3 |
| -# https://docs.semaphoreci.com/reference/pipeline-yaml-reference/ |
| 1 | +version: v1.0 # Pipeline schema: https://docs.semaphoreci.com/reference/pipeline-yaml/ |
| 2 | +name: "🔥 Phoenix CI Pipeline" |
4 | 3 |
|
5 |
| -version: v1.0 # Semaphore configuration version |
6 |
| -name: "🔥 Phoenix CI Pipeline" # Pipeline display name |
| 4 | +# --------------------------------------------------------------------------- |
| 5 | +# GLOBAL SETTINGS |
| 6 | +# --------------------------------------------------------------------------- |
7 | 7 |
|
8 |
| -# Define the machine type, OS image, and containers |
9 | 8 | agent:
|
10 | 9 | machine:
|
11 | 10 | type: {{ machine_type }}
|
12 | 11 | os_image: {{ os_image }}
|
| 12 | + containers: # Runtime & side‑service containers → https://docs.semaphoreci.com/reference/pipeline-yaml/#containers |
| 13 | + - name: main # Primary job container (Elixir + Node) |
| 14 | + image: 'registry.semaphoreci.com/elixir:1.16' # Image catalogue → https://docs.semaphoreci.com/using-semaphore/optimization/container-registry#convenience-and-language-images |
| 15 | + - name: postgres # Postgres DB for tests |
| 16 | + image: 'registry.semaphoreci.com/postgres:17' |
| 17 | + env_vars: |
| 18 | + - name: POSTGRES_PASSWORD |
| 19 | + value: postgres |
| 20 | + - name: POSTGRES_DB |
| 21 | + value: phoenix_test |
13 | 22 |
|
14 |
| - containers: |
15 |
| - - name: main |
16 |
| - image: 'registry.semaphoreci.com/elixir:1.15' # Elixir 1.15 container |
17 |
| - - name: postgres |
18 |
| - image: registry.semaphoreci.com/postgres:17 # PostgreSQL 17 for database operations |
19 |
| - - name: redis |
20 |
| - image: registry.semaphoreci.com/redis:7.0 # Redis 7.0 for caching |
21 |
| - |
22 |
| -# Configure when to stop the pipeline early |
23 |
| -fail_fast: |
24 |
| - stop: |
25 |
| - when: branch != 'main' # Stop all blocks if a job fails on non-main branches |
26 | 23 | auto_cancel:
|
27 |
| - running: |
28 |
| - when: branch != 'main' # Cancel running pipelines on non-main branches |
29 | 24 | queued:
|
30 |
| - when: branch = 'main' # Cancel queued pipelines on main branch |
| 25 | + when: 'true' |
| 26 | + |
| 27 | +fail_fast: |
| 28 | + cancel: |
| 29 | + when: branch != 'main' |
31 | 30 |
|
32 |
| -# Commands to run before each job |
33 | 31 | global_job_config:
|
| 32 | + env_vars: |
| 33 | + - name: MIX_ENV |
| 34 | + value: test |
34 | 35 | prologue:
|
35 | 36 | commands:
|
36 |
| - - checkout # Get the code from repository |
37 |
| - - mix local.hex --force # Install Hex package manager |
38 |
| - - mix local.rebar --force # Install rebar3 build tool |
39 |
| - - mix deps.get # Install dependencies |
40 |
| - - cache restore # Restore cached dependencies |
| 37 | + - checkout # Fetch repo at current commit |
| 38 | + - cache restore # Restore cached deps & _build |
| 39 | + |
| 40 | +# --------------------------------------------------------------------------- |
| 41 | +# BLOCKS |
| 42 | +# --------------------------------------------------------------------------- |
41 | 43 |
|
42 |
| -# Pipeline blocks represent groups of jobs that can run in parallel |
43 | 44 | blocks:
|
44 |
| - # Block for setting up dependencies and caching |
45 |
| - - name: "🛠️ Setup and Cache" |
46 |
| - dependencies: [] |
| 45 | + # ⚙️ Block 1: Install dependencies & compile – caches Hex/Rebar & JS assets |
| 46 | + - name: "⚙️ Install & Compile" |
47 | 47 | task:
|
48 | 48 | jobs:
|
49 |
| - - name: "📦 Install Dependencies" |
| 49 | + - name: "⚙️ Install & Compile" |
50 | 50 | commands:
|
51 |
| - - mix deps.compile # Compile dependencies |
52 |
| - - mix compile # Compile project |
53 |
| - - npm ci --prefix assets # Install Node.js dependencies |
54 |
| - - cache store # Cache dependencies for future runs |
| 51 | + - mix local.hex --force |
| 52 | + - mix local.rebar --force |
| 53 | + - mix deps.get # Fetch project dependencies |
| 54 | + - mix compile |
| 55 | + - npm install --prefix assets # Install JS dependencies for Phoenix assets |
| 56 | + - cache store # Cache deps & build artefacts |
55 | 57 |
|
56 |
| - # Block for asset compilation |
| 58 | + # 🎨 Block 2: Build & digest front‑end assets |
57 | 59 | - name: "🎨 Assets"
|
58 |
| - dependencies: ["🛠️ Setup and Cache"] |
| 60 | + dependencies: ["⚙️ Install & Compile"] |
59 | 61 | task:
|
60 | 62 | jobs:
|
61 | 63 | - name: "🖌️ Compile Assets"
|
62 | 64 | commands:
|
63 |
| - - npm run deploy --prefix assets # Build and digest assets |
64 |
| - - mix phx.digest # Digest and compress static files |
| 65 | + - npm run deploy --prefix assets # Build production JS/CSS bundle |
| 66 | + - mix phx.digest # Generate digested asset fingerprints |
65 | 67 |
|
66 |
| - # Block for code quality checks |
67 |
| - - name: "🔍 Code Quality" |
68 |
| - dependencies: ["🛠️ Setup and Cache"] |
| 68 | + # 🔍 Block 3: Static analysis – format, Credo, Dialyzer |
| 69 | + - name: "🔍 Static Analysis" |
| 70 | + dependencies: ["⚙️ Install & Compile"] |
69 | 71 | task:
|
70 | 72 | jobs:
|
71 |
| - - name: "✨ Lint and Format" |
| 73 | + - name: "🖌️ Format Check" |
72 | 74 | commands:
|
73 |
| - - mix format --check-formatted # Check code formatting |
74 |
| - - mix credo --strict # Run static code analysis |
75 |
| - - cd assets && npm run lint # Check JavaScript code |
76 |
| - |
77 |
| - # Block for security checks |
78 |
| - - name: "🔐 Security Checks" |
79 |
| - dependencies: ["🛠️ Setup and Cache"] |
80 |
| - task: |
81 |
| - jobs: |
82 |
| - - name: "🛡️ Security Scan" |
| 75 | + - mix format --check-formatted |
| 76 | + - name: "🕵️ Credo Lint" |
| 77 | + commands: |
| 78 | + - mix credo --strict |
| 79 | + - name: "🧠 Dialyzer" |
83 | 80 | commands:
|
84 |
| - - mix deps.audit # Check Elixir dependencies |
85 |
| - - mix sobelow --config # Run security-focused static analysis |
86 |
| - - cd assets && npm audit # Check Node.js dependencies |
| 81 | + - mix dialyzer --halt-exit-status |
87 | 82 |
|
88 |
| - # Block for type checking |
89 |
| - - name: "📊 Dialyzer" |
90 |
| - dependencies: ["🛠️ Setup and Cache"] |
| 83 | + # 🛡️ Block 4: Security scans – dependency & code audits |
| 84 | + - name: "🛡️ Security" |
| 85 | + dependencies: ["⚙️ Install & Compile"] |
91 | 86 | task:
|
92 | 87 | jobs:
|
93 |
| - - name: "🔎 Type Checking" |
| 88 | + - name: "🛡️ Sobelow & Audits" |
94 | 89 | commands:
|
95 |
| - - mix dialyzer # Run static type checking |
| 90 | + - mix deps.audit # Hex deps audit |
| 91 | + - mix sobelow --exit # Phoenix-specific security scan |
| 92 | + - npm audit --audit-level=moderate --prefix assets |
96 | 93 |
|
97 |
| - # Block for running tests |
98 |
| - - name: "🧪 Test Suite" |
99 |
| - dependencies: ["🛠️ Setup and Cache", "🎨 Assets"] |
| 94 | + # 🧪 Block 5: Tests (unit & integration) – depends only on security |
| 95 | + - name: "🧪 Tests" |
| 96 | + dependencies: ["🛡️ Security"] |
100 | 97 | task:
|
101 | 98 | env_vars:
|
102 |
| - - name: MIX_ENV |
103 |
| - value: test |
104 | 99 | - name: DATABASE_URL
|
105 |
| - value: postgresql://postgres@postgres:5432/app_test # Use container hostname |
106 |
| - - name: REDIS_URL |
107 |
| - value: redis://redis:6379 # Use container hostname |
| 100 | + value: "postgres://postgres:postgres@postgres:5432/phoenix_test" # Host "postgres" resolves to DB side‑container |
108 | 101 | jobs:
|
109 |
| - - name: "🟢 ExUnit Tests" |
110 |
| - parallelism: 4 # Run tests in parallel |
| 102 | + - name: "🧪 Unit Tests" |
111 | 103 | commands:
|
112 |
| - - mix ecto.create # Create test database |
113 |
| - - mix ecto.migrate # Run database migrations |
114 |
| - - mix test --cover # Run tests with coverage |
| 104 | + - mix deps.get # Fetch project dependencies |
| 105 | + - mix test --exclude integration --cover --export-coverage unit \ |
| 106 | + --formatter ExUnit.CLIFormatter \ |
| 107 | + --formatter JUnitFormatter \ |
| 108 | + --junit-report-file test_results/unit.xml |
| 109 | + - test-results gen-suite-report # Publish per‑suite report → https://docs.semaphoreci.com/using-semaphore/tests/test-reports --name "Unit Tests" --format junit --path test_results/unit.xml |
115 | 110 |
|
116 |
| - # Block for browser tests |
117 |
| - - name: "🌐 Browser Tests" |
118 |
| - dependencies: ["🧪 Test Suite"] |
119 |
| - task: |
120 |
| - jobs: |
121 |
| - - name: "🎭 Wallaby Tests" |
| 111 | + - name: "🔬 Integration Tests" |
122 | 112 | commands:
|
123 |
| - - mix wallaby.install # Install browser testing dependencies |
124 |
| - - mix test --only browser:true # Run browser tests |
| 113 | + - mix deps.get # Fetch project dependencies |
| 114 | + - mix test --only integration --cover --export-coverage integration \ |
| 115 | + --formatter ExUnit.CLIFormatter \ |
| 116 | + --formatter JUnitFormatter \ |
| 117 | + --junit-report-file test_results/integration.xml |
| 118 | + - test-results gen-suite-report # Publish per‑suite report → https://docs.semaphoreci.com/using-semaphore/tests/test-reports --name "Integration Tests" --format junit --path test_results/integration.xml |
125 | 119 |
|
126 |
| - # Block for deployment checks |
127 |
| - - name: "🚀 Deploy Checks" |
128 |
| - dependencies: ["🧪 Test Suite"] |
129 |
| - task: |
130 |
| - jobs: |
131 |
| - - name: "🔄 Migration Safety" |
132 |
| - commands: |
133 |
| - - mix ecto.migrations # Check pending migrations |
134 |
| - - mix phx.routes # Check route definitions |
135 |
| - - name: "📦 Release Build" |
136 |
| - commands: |
137 |
| - - MIX_ENV=prod mix release --dry-run # Test release building |
| 120 | +# --------------------------------------------------------------------------- |
| 121 | +# AFTER PIPELINE – coverage & reports |
| 122 | +# --------------------------------------------------------------------------- |
138 | 123 |
|
139 |
| - # Block for Docker image |
140 |
| - - name: "🐳 Docker" |
141 |
| - dependencies: ["🚀 Deploy Checks"] |
142 |
| - task: |
143 |
| - secrets: |
144 |
| - - name: dockerhub-credentials |
145 |
| - jobs: |
146 |
| - - name: "📦 Build and Push" |
147 |
| - commands: |
148 |
| - - echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USERNAME}" --password-stdin |
149 |
| - - docker build -t "${DOCKER_USERNAME}/phoenix-app:${SEMAPHORE_GIT_SHA:0:7}" . |
150 |
| - - docker push "${DOCKER_USERNAME}/phoenix-app:${SEMAPHORE_GIT_SHA:0:7}" |
| 124 | +after_pipeline: |
| 125 | + task: |
| 126 | + secrets: |
| 127 | + - name: coveralls # COVERALLS_REPO_TOKEN |
| 128 | + jobs: |
| 129 | + - name: "📤 Upload Coverage & Reports" |
| 130 | + commands: |
| 131 | + - mix coveralls.semaphore --exclude integration --import-cover cover # Upload coverage → https://github.com/parroty/excoveralls |
| 132 | + - test-results gen-pipeline-report # Aggregate & publish test reports → https://docs.semaphoreci.com/using-semaphore/tests/test-reports |
0 commit comments