Skip to content

Commit 6e0b982

Browse files
committed
aaa
1 parent a106c0c commit 6e0b982

File tree

10 files changed

+406
-1
lines changed

10 files changed

+406
-1
lines changed

.github/workflows/ci.yml

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
name: Continuous Integration
2+
on:
3+
push:
4+
branches:
5+
- main
6+
- dev
7+
pull_request:
8+
env:
9+
APP_NAME: etabli
10+
CONTAINER_REGISTRY: ghcr.io
11+
CONTAINER_IMAGE_FOLDER: ghcr.io/${{ github.repository }}
12+
NODE_OPTIONS: --max_old_space_size=4096
13+
NODE_VERSION: 18.19.0
14+
RUBY_VERSION: 3.2.2
15+
PLAYWRIGHT_BROWSERS_CACHE_FOLDER_SUFFIX: .cache/ms-playwright
16+
concurrency:
17+
# Prevent parallel builds of the same branch
18+
group: cicd-${{ github.ref }}
19+
cancel-in-progress: false
20+
jobs:
21+
requirements:
22+
name: Continuous Integration
23+
runs-on: ubuntu-latest
24+
permissions:
25+
contents: write
26+
issues: write
27+
pull-requests: write
28+
steps:
29+
- name: Checkout
30+
uses: actions/checkout@v4
31+
with:
32+
fetch-depth: 0
33+
34+
- name: Set environment for branch
35+
run: |
36+
if [[ $GITHUB_REF_NAME == 'main' ]]; then
37+
echo "APP_MODE=prod" >> $GITHUB_ENV
38+
echo "CLEVER_APP_ID=${{ secrets.CLEVER_APP_ID_PRODUCTION }}" >> $GITHUB_ENV
39+
elif [[ $GITHUB_REF_NAME == 'dev' ]]; then
40+
echo "APP_MODE=dev" >> $GITHUB_ENV
41+
echo "CLEVER_APP_ID=${{ secrets.CLEVER_APP_ID_DEVELOPMENT }}" >> $GITHUB_ENV
42+
else
43+
echo "APP_MODE=test" >> $GITHUB_ENV
44+
fi
45+
46+
- name: Setup Node.js
47+
uses: actions/setup-node@v3
48+
with:
49+
node-version: ${{ env.NODE_VERSION }}
50+
51+
- name: Setup Ruby
52+
uses: actions/setup-ruby@v1
53+
with:
54+
ruby-version: ${{ env.RUBY_VERSION }}
55+
56+
- name: Export npm store directory as an environment variable
57+
shell: bash
58+
run: |
59+
echo "STORE_PATH=$(npm config get cache)" >> $GITHUB_ENV
60+
61+
- uses: actions/cache@v3
62+
name: Setup npm cache
63+
with:
64+
path: ${{ env.STORE_PATH }}
65+
key: ${{ runner.os }}-npm-store-${{ hashFiles('**/package-lock.json') }}
66+
restore-keys: |
67+
${{ runner.os }}-npm-store-
68+
69+
- uses: actions/cache@v3
70+
name: Setup Next.js build cache
71+
with:
72+
path: ${{ github.workspace }}/.next/cache
73+
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}
74+
restore-keys: |
75+
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
76+
77+
- name: Install dependencies
78+
env:
79+
PLAYWRIGHT_BROWSERS_PATH: ${{ env.STORE_PATH }}/${{ env.PLAYWRIGHT_BROWSERS_CACHE_FOLDER_SUFFIX }}
80+
run: make deps
81+
82+
- name: Prepare linting
83+
run: make lint-prepare
84+
85+
- name: Lint
86+
run: make lint
87+
88+
- name: Format check
89+
run: make format-check
90+
91+
- name: Prepare tests
92+
run: make test-prepare
93+
94+
- name: Install `docker-compose` for local CI/CD simulations (https://github.com/nektos/act/issues/112#issuecomment-1387307297)
95+
if: ${{ env.ACT }}
96+
uses: KengoTODA/actions-setup-docker-compose@v1
97+
with:
98+
version: '2.14.2'
99+
- name: Install `Xvfb` and others to run browsers for end-to-end testing in local CI/CD simulations (https://github.com/nektos/act/issues/1300#issuecomment-1387344639)
100+
if: ${{ env.ACT }}
101+
run: sudo apt-get update && sudo apt-get install -y xvfb && npx playwright install-deps
102+
103+
- name: Test unit
104+
run: make test-unit
105+
106+
- name: Build
107+
env:
108+
SENTRY_URL: ${{ secrets.SENTRY_URL }}
109+
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
110+
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
111+
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
112+
SENTRY_RELEASE_UPLOAD: true
113+
run: make build
114+
115+
- name: Test end-to-end
116+
env:
117+
PLAYWRIGHT_BROWSERS_PATH: ${{ env.STORE_PATH }}/${{ env.PLAYWRIGHT_BROWSERS_CACHE_FOLDER_SUFFIX }}
118+
run: make test-e2e
119+
120+
# # Disabled since too long, need to consider if our Storybook e2e tests are sufficient
121+
# - name: Accessibility with Lighthouse
122+
# run: make accessibility
123+
# env:
124+
# NEXTJS_BUILD_OUTPUT_MODE: export
125+
# LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
126+
127+
- name: Publish to Chromatic
128+
if: ${{ !github.event.act }}
129+
uses: chromaui/action@v1
130+
env:
131+
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
132+
with:
133+
# Note: since we use `buildScriptName` we have to specify some of those parameters into the underlying `package.json` script named `chromatic`
134+
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
135+
buildScriptName: build
136+
autoAcceptChanges: true
137+
onlyChanged: true
138+
externals: public/**
139+
exitZeroOnChanges: true
140+
141+
- name: Log in to the Container registry
142+
if: ${{ !github.event.act && (github.ref_name == 'dev' || github.ref_name == 'main') }}
143+
uses: docker/login-action@v2
144+
with:
145+
registry: ${{ env.CONTAINER_REGISTRY }}
146+
username: ${{ github.actor }}
147+
password: ${{ secrets.GITHUB_TOKEN }}
148+
149+
- name: Build and push the application Docker image
150+
if: ${{ !github.event.act && (github.ref_name == 'dev' || github.ref_name == 'main') }}
151+
uses: docker/build-push-action@v5
152+
with:
153+
push: true
154+
tags: ${{ env.CONTAINER_IMAGE_FOLDER }}/${{ env.APP_NAME }}-${{ github.ref_name }}:${{ github.sha }},${{ env.CONTAINER_IMAGE_FOLDER }}/${{ env.APP_NAME }}-${{ github.ref_name }}:latest
155+
cache-from: type=gha
156+
cache-to: type=gha,mode=max
157+
158+
- name: Deploy to Clever Cloud
159+
if: ${{ !github.event.act && (github.ref_name == 'dev' || github.ref_name == 'main') }}
160+
uses: 47ng/actions-clever-cloud@v1.3.1
161+
with:
162+
appID: ${{ env.CLEVER_APP_ID }}
163+
force: true
164+
quiet: true # disable copying into GitHub Actions all logs from Clever Cloud
165+
env:
166+
CLEVER_TOKEN: ${{ secrets.CLEVER_TOKEN }}
167+
CLEVER_SECRET: ${{ secrets.CLEVER_SECRET }}

.github/workflows/clean-images.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
name: Clean old Docker images
2+
on:
3+
schedule:
4+
- cron: '0 7 * * 1' # Every monday at 7am
5+
workflow_dispatch: # Allow triggering this pipeline manually

.github/workflows/pr.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Pull Request
2+
3+
on: [pull_request]
4+
5+
jobs:
6+
build:
7+
runs-on: ubuntu-latest
8+
9+
strategy:
10+
matrix:
11+
node-version: [16.15.0]
12+
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v3
16+
with:
17+
fetch-depth: 0
18+
19+
- name: Setup Node.js ${{ matrix.node-version }}
20+
uses: actions/setup-node@v3
21+
with:
22+
node-version: ${{ matrix.node-version }}
23+
24+
- uses: pnpm/action-setup@v2
25+
name: Install pnpm
26+
id: pnpm-install
27+
with:
28+
version: 7.27.1
29+
run_install: false
30+
31+
- name: Get pnpm store directory
32+
id: pnpm-cache
33+
shell: bash
34+
run: |
35+
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
36+
37+
- uses: actions/cache@v3
38+
name: Setup pnpm cache
39+
with:
40+
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
41+
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
42+
restore-keys: |
43+
${{ runner.os }}-pnpm-store-
44+
45+
- run: make deps
46+
- run: make lint
47+
- run: make test
48+
- run: make build
49+
# - run: make coverage
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
name: Prepare the Docker runner image
2+
on:
3+
workflow_dispatch: # Allow triggering this pipeline manually

Dockerfile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# [IMPORTANT] Must be built from the root of the project for the COPY/paths to work
2+
3+
ARG PORT=3000
4+
5+
FROM ghcr.io/betagouv/etabli/etabli-${BRANCH}:latest
6+
7+
RUN addgroup --system --gid 1001 nodejs
8+
RUN adduser --system --uid 1001 nextjs
9+
10+
USER nextjs
11+
12+
COPY --chown=nextjs:nodejs ".next/standalone" ./
13+
COPY --chown=nextjs:nodejs ".next/static" "./.next/static"
14+
COPY --chown=nextjs:nodejs "public" "./public"
15+
COPY --chown=nextjs:nodejs "start-and-wait-to-init.sh" ./
16+
17+
ENV PORT $PORT
18+
EXPOSE $PORT
19+
20+
CMD start-and-wait-to-init.sh

Dockerfile.clevercloud

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# We didn't want to rebuild everything in the Clever Cloud pipeline so we pushed an image from GitHub to be retrieved here without much processing
2+
3+
FROM ghcr.io/betagouv/etabli/etabli-${BRANCH}:latest

Dockerfile.runner

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
ARG NODE_VERSION=18.19.0
2+
ARG RUBY_VERSION=3.2.2-r1
3+
ARG PYTHON_VERSION=
4+
5+
FROM node:${NODE_VERSION}-alpine
6+
7+
RUN apk add --no-cache 'ruby=${RUBY_VERSION}'
8+
RUN apk update
9+
10+
# Install tools
11+
RUN gem install bundler
12+
RUN bundle --gemfile src/bibliothecary/Gemfile
13+
14+
# TODO:
15+
# TODO: "Don't run Bundler as root. Installing your bundle as root will break this application for all non-root users on this machine."
16+
# TODO:
17+
# TODO: ruby, python, and only get the final image (the builder should be outside in the GitHub runner)
18+
# TODO:
19+
# TODO:
20+
# TODO:

Makefile

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
define HELP_TEXT
2+
3+
Makefile commands
4+
5+
make deps - Install dependent programs and libraries
6+
make ... - (see the Makefile)
7+
8+
endef
9+
10+
help:
11+
$(info $(HELP_TEXT))
12+
13+
build:
14+
npm run build
15+
#--mode prod
16+
17+
build-dev:
18+
npm run build
19+
#--mode dev
20+
21+
serve:
22+
npm run dev
23+
#--mode test
24+
25+
serve-dev:
26+
npm run dev
27+
#--mode dev
28+
29+
lint-prepare:
30+
npm run lint:prepare
31+
32+
lint:
33+
npm run lint
34+
35+
test-prepare:
36+
npm run test:prepare
37+
38+
test-unit:
39+
npm run test:unit
40+
41+
test-unit-watch:
42+
npm run test:unit:watch
43+
44+
test-e2e:
45+
npm run test:e2e:headless
46+
47+
clean:
48+
npm run clean
49+
50+
accessibility:
51+
npm run accessibility
52+
53+
accessibility-open:
54+
npm run accessibility:open
55+
56+
deps:
57+
npm install
58+
59+
tools-up:
60+
docker-compose up -d
61+
62+
tools-down:
63+
docker-compose down
64+
65+
format:
66+
npm run format
67+
68+
format-check:
69+
npm run format:check
70+
71+
simulate-cicd-with-push:
72+
# Install `act` through a package manager to make it working
73+
#
74+
# Notes:
75+
# - there is no way to specify the pipeline branch, you must locally change it
76+
# - you can have weird issues like "unable to get git", try to set your local head to the remote one (with your changes uncommitted)
77+
# - caching:
78+
# - for now the cache does not work and even if there is https://github.com/sp-ricard-valverde/github-act-cache-server it's a bit overheaded for a ponctual simulation
79+
# - using "--bind" is not ideal because `npm` will recreate the whole "node_modules" on the host, so we have to do `npm install` then (it would make sense for a computer dedicated to this)
80+
# - so we use "--reuse" that keeps using the existing docker container if any, to avoid downloading a new time each dependency. If you get weird behavior you can still remove the docker container from `act` and restart the command
81+
# - we inject a meaningful commit SHA into "SOURCE_VERSION" otherwise a Jest process will fail since we use it for Sentry stuff in the Next.js app
82+
# - the default image is missing browsers stuff for e2e tests and `docker-compose`, we added 2 steps in the workflow to not deal with a custom image not officially supported (and the full official image is around 15GB... we don't want that either)
83+
# - `.actrc` breaks `act` commands in specific situations, we avoid using it to factorize commands
84+
act push --reuse --env-file .github/act/.env --env SOURCE_VERSION="$(git rev-parse @{upstream})" --eventpath .github/act/event.json

next.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const moduleExports = async () => {
3838
let standardModuleExports = {
3939
reactStrictMode: true,
4040
swcMinify: true,
41-
output: 'standalone', // To debug locally the `next start` comment this line (it will avoid trying to mess with the assembling folders logic of standalone mode)
41+
output: process.env.NEXTJS_BUILD_OUTPUT || 'standalone', // To debug locally the `next start` comment this line (it will avoid trying to mess with the assembling folders logic of standalone mode)
4242
env: {
4343
// Those will replace `process.env.*` with hardcoded values (useful when the value is calculated during the build time)
4444
SENTRY_RELEASE_TAG: appHumanVersion,

0 commit comments

Comments
 (0)