default: image: registry.gitlab.com/gitlab-org/gitlab-docs:base tags: - gitlab-org # Check Ruby version and install gems before_script: - ruby -v - bundle config set path 'vendor' - NOKOGIRI_USE_SYSTEM_LIBRARIES=1 bundle install --jobs 4 .yarn: before_script: - yarn install --cache-folder .yarn-cache stages: - build-images - build - test - pre-deploy - deploy - post-deploy # # Pick the remote branch, by default master (see the Rakefile for more info) # variables: BRANCH_EE: 'master' BRANCH_OMNIBUS: 'master' BRANCH_RUNNER: 'master' BRANCH_CHARTS: 'master' BUNDLE_PATH__SYSTEM: 'false' GIT_DEPTH: '20' # # Retry a job automatically if it fails (2 times) # .retry: retry: 2 # # Rules to determine which pipelines jobs will run in. # .rules_scheduled: rules: - if: '$CI_PIPELINE_SOURCE != "schedule"' when: never - if: '$PIPELINE_SCHEDULE_TIMING == "weekly"' - if: '$PIPELINE_SCHEDULE_TIMING == "hourly"' when: manual allow_failure: true - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' when: manual allow_failure: true .rules_scheduled_manual: rules: - if: '$CI_PIPELINE_SOURCE == "schedule"' when: manual allow_failure: true - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' when: manual allow_failure: true .rules_chores: rules: - if: '$CI_PIPELINE_SOURCE != "schedule"' when: never - if: '$PIPELINE_SCHEDULE_TIMING == "hourly"' when: manual allow_failure: true .rules_site_tests: rules: - if: '$CI_PIPELINE_SOURCE == "schedule"' - if: '$CI_MERGE_REQUEST_ID' - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' - if: '$CI_COMMIT_BRANCH =~ /^\d{1,2}\.\d{1,2}$/' .rules_prod: rules: - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' - if: '$CI_COMMIT_BRANCH =~ /^\d{1,2}\.\d{1,2}$/' .rules_pages: rules: - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' .rules_dev: rules: - if: '$CI_MERGE_REQUEST_ID' - if: '$CI_COMMIT_BRANCH =~ /docs-preview/' # # Caching keys # .cache_gem: cache: key: files: - Gemfile.lock paths: - vendor/ruby .cache_gem_yarn: cache: key: files: - Gemfile.lock - yarn.lock paths: - vendor/ruby - .yarn-cache/ .cache_yarn: cache: key: files: - yarn.lock paths: - .yarn-cache/ ############################################### # Build the website # ############################################### .build_base: image: registry.gitlab.com/gitlab-org/gitlab-docs:bootstrap stage: build extends: - .cache_gem_yarn - .retry script: - yarn install --cache-folder .yarn-cache - bundle exec rake setup_git default - bundle exec nanoc compile -VV # Symlink all README.html to index.html so that we can have clean URLs - for i in `find public -name README.html`; do ln -sf README.html $(dirname $i)/index.html; done # Remove CE dir and symlink EE to CE - if [ $CI_PIPELINE_SOURCE != 'pipeline' ]; then cd public && rm -rf ce && ln -s ee ce && cd ../; fi # Calculate sizes before and after minifying/gzipping the static files (HTML, CSS, JS) - SIZE_BEFORE=$(du -sh public/ | awk '{print $1}') # Minify the assets of the resulting site - ./scripts/minify-assets.sh ./ public/ - SIZE_AFTER_MINIFY=$(du -sh public/ | awk '{print $1}') # Use gzip to compress static content for faster web serving # https://docs.gitlab.com/ee/user/project/pages/introduction.html#serving-compressed-assets - find public/ -type f \( -iname "*.html" -o -iname "*.js" -o -iname "*.css" -o -iname "*.svg" \) -exec gzip --keep --best --force --verbose {} \; - SIZE_AFTER_GZIP=$(du -sh public/ | awk '{print $1}') # Print size results - echo "Minify and compress the static assets (HTML, CSS, JS)" - echo - echo -e "Size before minifying and gzipping ..... $SIZE_BEFORE\nSize after minifying ................... $SIZE_AFTER_MINIFY\nSize after adding gzipped versions ..... $SIZE_AFTER_GZIP" artifacts: paths: - public expire_in: 1d # # Compile only on the default and stable branches # compile_prod: extends: - .rules_prod - .build_base variables: NANOC_ENV: 'production' # # Compile on all branches except the default branch # compile_dev: extends: - .rules_dev - .build_base ############################################### # Test the website # ############################################### # # Test internal links and anchors with nanoc # test_internal_links_and_anchors: image: registry.gitlab.com/gitlab-org/gitlab-docs/lint:latest extends: - .rules_site_tests - .cache_gem stage: test script: - bundle exec nanoc check internal_links - bundle exec nanoc check internal_anchors # # Run rspec tests # rspec: extends: - .rules_site_tests - .cache_gem needs: [] stage: test script: - bundle exec rspec # # Run JavaScript tests # jest: extends: - .rules_site_tests - .cache_yarn - .yarn needs: [] stage: test script: - yarn test # # Lint JavaScript # js_lint: extends: - .rules_site_tests - .cache_yarn - .yarn needs: [] stage: test script: - yarn eslint - yarn prettier # # SCSS linting # scss_lint: extends: - .rules_site_tests - .cache_gem - .retry needs: [] stage: test script: - bundle exec scss-lint # # Yamllint of *.yml for .gitlab-ci.yml. # This uses rules from project root `.yamllint`. # yaml_lint: extends: - .rules_site_tests needs: [] stage: test image: sdesbure/yamllint:latest before_script: [] script: - yamllint .gitlab-ci.yml content/_data # # Check for broken external links, weekly pipelines only # test_external_links: extends: - .cache_gem - .rules_chores stage: test script: - bundle exec nanoc check external_links # # Run markdownlint to find EOL whitespace to clean up # test_EOL_whitespace: extends: - .rules_chores stage: test image: registry.gitlab.com/gitlab-org/gitlab-docs/lint:latest before_script: [] dependencies: [] script: - bundle exec rake setup_git default - cd tmp - markdownlint --version - echo "{" > .markdownlint.json - 'echo " \"default\": false," >> .markdownlint.json' - 'echo " \"no-trailing-spaces\": true," >> .markdownlint.json' - echo "}" >> .markdownlint.json - markdownlint -c .markdownlint.json **/*.md ############################################### # Review Apps # ############################################### # # Deploy the Review App on a dev server # review: stage: deploy extends: - .retry variables: GIT_STRATEGY: none needs: - compile_dev before_script: [] cache: {} script: # Rsync to the Pages dir - rsync -av --delete public /srv/nginx/pages/$CI_COMMIT_REF_SLUG # Remove public directory so that the next review app can run in a # clean environment (limitation of the shell executor). - rm -rf public environment: name: review/$CI_COMMIT_REF_SLUG url: http://$CI_COMMIT_REF_SLUG.$APPS_DOMAIN on_stop: review_stop rules: - if: '$CI_PROJECT_PATH != "gitlab-org/gitlab-docs"' when: never - if: '$CI_MERGE_REQUEST_ID' - if: '$CI_COMMIT_BRANCH =~ /docs-preview/' tags: - nginx - review-apps # # Stop the Review App # review_stop: stage: deploy extends: - .retry variables: GIT_STRATEGY: none needs: [] artifacts: {} before_script: [] cache: {} script: - rm -rf public /srv/nginx/pages/$CI_COMMIT_REF_SLUG environment: name: review/$CI_COMMIT_REF_SLUG action: stop rules: - if: '$CI_PROJECT_PATH != "gitlab-org/gitlab-docs"' when: never - if: '$CI_MERGE_REQUEST_ID || $CI_COMMIT_BRANCH =~ /docs-preview/' allow_failure: true when: manual tags: - nginx - review-apps ############################################### # GitLab Pages (production) # ############################################### # # Deploy to production with GitLab Pages # pages: resource_group: pages extends: - .rules_pages - .retry image: registry.gitlab.com/gitlab-org/gitlab-docs:latest stage: deploy variables: GIT_STRATEGY: none before_script: [] cache: {} environment: name: production url: https://docs.gitlab.com # We are using dependencies, because we do not want to # re-deploy if the previous stages failed. dependencies: - compile_prod # Contains the public directory script: # # We want to use the artifacts of the compile_prod job as # the latest docs deployment, and the other versions are # taken from /usr/share/nginx/html which are included in # the image we pull from. # - mv /usr/share/nginx/html/1* public/ artifacts: paths: - public expire_in: 1d ############################################### # Docker images builds # ############################################### # # Reuse some common commands # .docker_prepare: extends: - .retry image: docker:latest tags: - gitlab-org-docker services: - docker:19.03.5-dind before_script: - docker info - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY # # GitLab docs lint image containing all test tools # image:docs-lint: extends: - .rules_scheduled - .docker_prepare stage: build-images variables: RUBY_VERSION: '2.7.2' ALPINE_VERSION: '3.12' VALE_VERSION: '2.4.3' MARKDOWNLINT_VERSION: '0.24.0' IMAGE_NAME: $CI_REGISTRY_IMAGE/lint:ruby-$RUBY_VERSION-alpine-$ALPINE_VERSION-vale-$VALE_VERSION-markdownlint-$MARKDOWNLINT_VERSION IMAGE_LATEST: $CI_REGISTRY_IMAGE/lint:latest DOCKERFILE: dockerfiles/Dockerfile.gitlab-docs-lint script: - docker build --build-arg RUBY_VERSION=${RUBY_VERSION} --build-arg ALPINE_VERSION=${ALPINE_VERSION} --build-arg VALE_VERSION=${VALE_VERSION} --build-arg MARKDOWNLINT_VERSION=${MARKDOWNLINT_VERSION} --build-arg CI_COMMIT_REF_NAME=${CI_COMMIT_REF_NAME} -t $IMAGE_NAME -f $DOCKERFILE . - docker tag $IMAGE_NAME $IMAGE_LATEST - docker push $IMAGE_NAME - docker push $IMAGE_LATEST environment: name: registry/docs-lint image:docs-lint-markdown: extends: - .rules_scheduled - .docker_prepare stage: build-images variables: ALPINE_VERSION: '3.12' VALE_VERSION: '2.6.1' MARKDOWNLINT_VERSION: '0.24.0' IMAGE_NAME: $CI_REGISTRY_IMAGE/lint-markdown:alpine-$ALPINE_VERSION-vale-$VALE_VERSION-markdownlint-$MARKDOWNLINT_VERSION DOCKERFILE: dockerfiles/Dockerfile.gitlab-docs-lint-markdown script: - docker build --build-arg ALPINE_VERSION=${ALPINE_VERSION} --build-arg VALE_VERSION=${VALE_VERSION} --build-arg MARKDOWNLINT_VERSION=${MARKDOWNLINT_VERSION} --build-arg CI_COMMIT_REF_NAME=${CI_COMMIT_REF_NAME} -t $IMAGE_NAME -f $DOCKERFILE . - docker push $IMAGE_NAME environment: name: registry/docs-lint # # GitLab docs image # image:gitlab-docs-base: extends: - .rules_scheduled_manual - .docker_prepare stage: build-images variables: IMAGE_NAME: $CI_REGISTRY_IMAGE:base DOCKERFILE: dockerfiles/Dockerfile.gitlab-docs-base script: - docker build -t $IMAGE_NAME -f $DOCKERFILE . - docker push $IMAGE_NAME environment: name: registry/docs-base # # Helper Docker image containing all build dependencies. # It must be rebuilt every time Gemfile and/or Gemfile.lock changes. # image:bootstrap: extends: - .rules_scheduled - .docker_prepare stage: build-images variables: IMAGE_NAME: $CI_REGISTRY_IMAGE:bootstrap DOCKERFILE: dockerfiles/Dockerfile.bootstrap script: - docker build -t $IMAGE_NAME -f $DOCKERFILE . - docker push $IMAGE_NAME environment: name: registry/docs-bootstrap # # Helper Docker image that builds the gitlab-docs website # image:builder-onbuild: extends: - .rules_scheduled_manual - .docker_prepare stage: build-images variables: IMAGE_NAME: $CI_REGISTRY_IMAGE:builder-onbuild DOCKERFILE: dockerfiles/Dockerfile.builder.onbuild script: - docker build -t $IMAGE_NAME -f $DOCKERFILE . - docker push $IMAGE_NAME environment: name: registry/builder-onbuild # # Helper Docker image that copies the final HTML files in a smaller image # (no rubygems included) # image:nginx-onbuild: extends: - .rules_scheduled_manual - .docker_prepare stage: build-images variables: IMAGE_NAME: $CI_REGISTRY_IMAGE:nginx-onbuild DOCKERFILE: dockerfiles/Dockerfile.nginx.onbuild script: - docker build -t $IMAGE_NAME -f $DOCKERFILE . - docker push $IMAGE_NAME environment: name: registry/nginx-onbuild # # Final Docker image containing a single version # It is based on Dockerfile.single for each branch # image:docs-single: extends: - .docker_prepare stage: pre-deploy artifacts: {} cache: {} dependencies: [] variables: NANOC_ENV: 'production' IMAGE_NAME: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME DOCKERFILE: Dockerfile.$CI_COMMIT_REF_NAME environment: name: registry/$CI_COMMIT_REF_SLUG script: - docker build --build-arg NANOC_ENV=${NANOC_ENV} --build-arg CI_COMMIT_REF_NAME=${CI_COMMIT_REF_NAME} -t $IMAGE_NAME -f $DOCKERFILE . - docker push $IMAGE_NAME # Only branches with versions like 10.4 rules: - if: '$CI_COMMIT_BRANCH =~ /^\d{1,2}\.\d{1,2}$/' # # Final Docker image containing all the archives # image:docs-archives: extends: - .rules_scheduled - .docker_prepare stage: pre-deploy artifacts: {} cache: {} dependencies: [] variables: IMAGE_NAME: $CI_REGISTRY_IMAGE:archives environment: name: registry/archives script: - docker build -t $IMAGE_NAME -f dockerfiles/Dockerfile.archives . - docker push $IMAGE_NAME # # Build master containing the online archives and latest docs (on schedules) # image:docs-latest: extends: - .rules_scheduled - .docker_prepare stage: pre-deploy artifacts: {} cache: {} dependencies: [] variables: NANOC_ENV: 'production' IMAGE_NAME: $CI_REGISTRY_IMAGE:latest DOCKERFILE: Dockerfile.$CI_COMMIT_REF_NAME environment: name: registry/latest script: - docker build --build-arg NANOC_ENV=${NANOC_ENV} --build-arg CI_COMMIT_REF_NAME=${CI_COMMIT_REF_NAME} -t $IMAGE_NAME -f $DOCKERFILE . - docker push $IMAGE_NAME