diff --git a/.env b/.env new file mode 100644 index 00000000..f5ff19b2 --- /dev/null +++ b/.env @@ -0,0 +1,8 @@ +APP_WORKING_DIR = "/home/jenkins/agent" +NODE_ENV = 'production' +TZ = "UTC" +# // Amount of available vCPUs, to avoid OOM - https://www.gatsbyjs.com/docs/how-to/performance/resolving-out-of-memory-issues/#try-reducing-the-number-of-cores +# // https://github.com/jenkins-infra/jenkins-infra/tree/production/hieradata/clients/controller.ci.jenkins.io.yaml#L327 +GATSBY_CPU_COUNT = "4" +GATSBY_TELEMETRY_DISABLED = "1" +NODE_OPTIONS = "--no-warnings" diff --git a/Jenkinsfile b/Jenkinsfile index a7224bb2..07bdd56e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -10,96 +10,114 @@ pipeline { label 'linux-arm64-docker || arm64linux' } - environment { - NODE_ENV = 'production' - TZ = "UTC" - // Amount of available vCPUs, to avoid OOM - https://www.gatsbyjs.com/docs/how-to/performance/resolving-out-of-memory-issues/#try-reducing-the-number-of-cores - // https://github.com/jenkins-infra/jenkins-infra/tree/production/hieradata/clients/controller.ci.jenkins.io.yaml#L327 - GATSBY_CPU_COUNT = "4" - // Added the below to fix permissions issue with the cache - GATSBY_CACHE_DIR = "${env.WORKSPACE}/.gatsby-cache" - GATSBY_INTERNAL_CACHE_DIR = "${env.WORKSPACE}/.cache" - GATSBY_TELEMETRY_DISABLED = "1" - NODE_OPTIONS = "--no-warnings" - } - stages { - stage('Check for typos') { - steps { - sh ''' - curl -qsL https://github.com/crate-ci/typos/releases/download/v1.33.1/typos-v1.33.1-x86_64-unknown-linux-musl.tar.gz | tar xvzf - ./typos - ./typos --format sarif > typos.sarif || true - ''' - } - post { - always { - recordIssues(tools: [sarif(id: 'typos', name: 'Typos', pattern: 'typos.sarif')]) - } - } - } + stage('Test and build') { + parallel { + stage('Main CI') { + stages { + stage('Check for typos') { + steps { + sh ''' + curl - qsL https: //github.com/crate-ci/typos/releases/download/v1.33.1/typos-v1.33.1-x86_64-unknown-linux-musl.tar.gz | tar xvzf - ./typos + . / typos--format sarif > typos.sarif || true + ''' + } + post { + always { + recordIssues(tools: [sarif(id: 'typos', name: 'Typos', pattern: 'typos.sarif')]) + } + } + } - stage('Check Tooling') { - steps { - sh ''' - node --version - npm --version - ''' - } - } + stage('Check Tooling') { + steps { + sh ''' + node --version + npm --version + ''' + } + } - stage('Install Dependencies') { - environment { - NODE_ENV = 'development' - } - steps { - sh 'npm ci' - } - } + stage('Install Dependencies') { + environment { + NODE_ENV = 'development' + } + steps { + sh 'npm ci' + } + } - stage('Lint and Test') { - environment { - NODE_ENV = "development" - } - steps { - sh 'npm run lint && npx eslint --format checkstyle > eslint.xml' - } - post { - always { - recordIssues(tools: [checkStyle(pattern: 'eslint.xml')]) - } - } - } + stage('Lint and Test') { + environment { + NODE_ENV = "development" + } + steps { + sh 'npm run lint && npx eslint --format checkstyle > eslint.xml' + } + post { + always { + recordIssues(tools: [checkStyle(pattern: 'eslint.xml')]) + } + } + } - stage('Build PR') { - when { changeRequest() } - environment { - NODE_ENV = 'development' - } - steps { - sh 'npm run build' - } - } + stage('Build PR') { + when { + changeRequest() + } + environment { + NODE_ENV = 'development' + } + steps { + sh ''' + source ./.env + npm run build + ''' + } + } - stage('Deploy PR to preview site') { - when { - allOf{ - changeRequest target: 'main' - // Only deploy to production from infra.ci.jenkins.io - expression { infra.isInfra() } - } - } - environment { - NETLIFY_AUTH_TOKEN = credentials('netlify-auth-token') - } - steps { - sh 'netlify-deploy --draft=true --siteName "jenkins-is-the-way" --title "Preview deploy for ${CHANGE_ID}" --alias "deploy-preview-${CHANGE_ID}" -d ./public' - } - post { - success { - recordDeployment('jenkins-infra', 'stories', pullRequest.head, 'success', "https://deploy-preview-${CHANGE_ID}--jenkins-is-the-way.netlify.app") + stage('Deploy PR to preview site') { + when { + allOf { + changeRequest target: 'main' + // Only deploy to production from infra.ci.jenkins.io + expression { infra.isInfra() } + } + } + environment { + NETLIFY_AUTH_TOKEN = credentials('netlify-auth-token') + } + steps { + sh 'netlify-deploy --draft=true --siteName "jenkins-is-the-way" --title "Preview deploy for ${CHANGE_ID}" --alias "deploy-preview-${CHANGE_ID}" -d ./public' + } + post { + success { + recordDeployment('jenkins-infra', 'stories', pullRequest.head, 'success', "https://deploy-preview-${CHANGE_ID}--jenkins-is-the-way.netlify.app") + } + failure { + recordDeployment('jenkins-infra', 'stories', pullRequest.head, 'failure', "https://deploy-preview-${CHANGE_ID}--jenkins-is-the-way.netlify.app") + } + } + } + } } - failure { - recordDeployment('jenkins-infra', 'stories', pullRequest.head, 'failure', "https://deploy-preview-${CHANGE_ID}--jenkins-is-the-way.netlify.app") + + stage('Test Docker Compose') { + when { + allOf { + changeRequest() + // Only run docker tests on non-infra.ci.jenkins.io + expression { !infra.isInfra() } + } + } + steps { + sh ''' + source ./.env + docker compose up --detach --wait + docker compose run --rm stories_webapp env + docker compose down + ''' + } } } } @@ -109,7 +127,10 @@ pipeline { branch "main" } steps { - sh 'npm run build' + sh ''' + source ./.env + npm run build + ''' } } diff --git a/README.md b/README.md index 05901476..3c996165 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,21 @@ npm run develop Open [http://localhost:8000](http://localhost:8000) on your browser to see the result +## Alternative Development Setup: Docker Compose + +You can also use Docker Compose for local development. + +### How to Use + +1. Ensure you have [Docker](https://www.docker.com/products/docker-desktop/) and [Docker Compose](https://docs.docker.com/compose/) installed. +2. In the project **root**, run: + ```bash + docker compose up + ``` +3. Open [http://localhost:8000](http://localhost:8000) in your browser. + +> Note: You can override the number of CPUs used by Gatsby by setting the `GATSBY_CPU_COUNT` environment variable to avoid OOM. + ## Code Quality Tools ### Formatting diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..9b11e5c1 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,34 @@ +services: + stories_webapp: + # TODO: track version with updatecli - ref. https://github.com/jenkins-infra/jenkins-infra/blob/efe90908529525bb3c9e61c2eb920ada3b968f1a/updatecli/updatecli.d/jenkinscontroller-tools-maven.yaml#L17-L22 + image: jenkinsciinfra/jenkins-agent-ubuntu-22.04:2.102.0 + ports: + - "8000:8000" + + environment: + # Can pass the "GATSBY_CPU_COUNT" from your shell straight through to your containers, if it is set and not empty, otherwise the default value will be used to avoid OOM issues + GATSBY_CPU_COUNT: ${GATSBY_CPU_COUNT:-physical_cores} + CHOKIDAR_USEPOLLING: "true" + NODE_ENV: development + APP_WORKING_DIR: $APP_WORKING_DIR + + volumes: + - .:$APP_WORKING_DIR/workspace + - ./src:$APP_WORKING_DIR/src + - stories_node_modules:/tmp/node_modules + + working_dir: $APP_WORKING_DIR + user: jenkins + entrypoint: [] + command: > + sh -c " + ln -s /tmp/node_modules ${APP_WORKING_DIR}/node_modules || true && + cp -r ${APP_WORKING_DIR}/workspace/. . || true && + node --version && + npm --version && + npm ci && + npm run develop -- -H 0.0.0.0 -p 8000 + " + +volumes: + stories_node_modules: