fradrive/.gitlab-ci.yml

589 lines
17 KiB
YAML

# SPDX-FileCopyrightText: 2022-2024 Sarah Vaupel <sarah.vaupel@uniworx.de>, Gregor Kleen <gregor@kleen.consulting>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
### IMPORTANT NOTICE ###
# Our pipeline consists of static and dynamic parts.
#
# This file only contains the static parts of our pipeline.
# Dynamic jobs are defined in .gitlab-ci/frontend.yml and .gitlab-ci/backend.yml.
# These are used as a template to generate downstream (child) pipelines during
# the runtime of the upstream (parent) pipeline.
###
# workflow:
# rules:
# - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
# - if: $CI_MERGE_REQUEST_ID
# - if: $CI_COMMIT_TAG =~ /^v/
# - if: $CI_COMMIT_TAG =~ /^t/
# - if: $CI_COMMIT_TAG =~ /^d/
variables:
IMAGE_BUILDER: quay.io/buildah/stable:latest
FRONTEND_IMAGE_DEPENDENCIES:
docker/frontend/Dockerfile
package.json
package-lock.json
webpack.config.js
BACKEND_IMAGE_DEPENDENCIES:
docker/backend/Dockerfile
package.yaml
stack.yaml
stack.yaml.lock
default:
image:
name: ${CI_REGISTRY}/uniworx/containers/debian:12.5
entrypoint: [""]
docker:
platform: x86_64
artifacts:
name: "${CI_JOB_NAME}-${CI_COMMIT_SHORT_SHA}"
expire_in: "1 day"
retry: 2
interruptible: true
stages:
- setup
- frontend
- backend
- release
setup:dynamic:
stage: setup
before_script:
- apt-get -y update
- apt-get -y install git
variables:
GIT_DEPTH: 99999
GIT_STRATEGY: clone
GIT_LOG_COMMAND: 'git log --max-count=1 --date=format:%Y-%m-%dT%H-%M --pretty=format:%cd'
script:
- echo "${FRONTEND_IMAGE_DEPENDENCIES}"
- echo "${BACKEND_IMAGE_DEPENDENCIES}"
- FRONTEND_IMAGE_VERSION=`${GIT_LOG_COMMAND} ${FRONTEND_IMAGE_DEPENDENCIES} | tee frontend-image-version`
- BACKEND_IMAGE_VERSION=`${GIT_LOG_COMMAND} ${BACKEND_IMAGE_DEPENDENCIES} | tee backend-image-version`
- 'echo "FRONTEND_IMAGE_VERSION: ${FRONTEND_IMAGE_VERSION}, BACKEND_IMAGE_VERSION: ${BACKEND_IMAGE_VERSION}"'
- cat .gitlab-ci/frontend.yml | .gitlab-ci/dynamci.pl FRONTEND_IMAGE_VERSION=${FRONTEND_IMAGE_VERSION} > frontend.yml
- cat .gitlab-ci/backend.yml | .gitlab-ci/dynamci.pl BACKEND_IMAGE_VERSION=${BACKEND_IMAGE_VERSION} PARENT_PIPELINE_ID=${CI_PIPELINE_ID} > backend.yml
artifacts:
paths:
- frontend-image-version
- backend-image-version
- frontend.yml
- backend.yml
rules:
- when: always
setup:containers:frontend: &setup-container
stage: setup
needs:
- setup:dynamic
image: ${IMAGE_BUILDER}
variables:
IMAGE_TYPE: frontend
before_script: &container-before
- IMAGE_VERSION=`cat ${IMAGE_TYPE}-image-version`
- IMAGE_TAG=${CI_COMMIT_REF_SLUG}/${IMAGE_TYPE}:${IMAGE_VERSION}
- REGISTRY_DESTINATION=${CI_REGISTRY_IMAGE}/${CI_COMMIT_REF_SLUG}/${IMAGE_TYPE}:${IMAGE_VERSION}
script:
- curl --request GET --header "PRIVATE-TOKEN:${REGISTRY_AUTH_TOKEN}" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/registry/repositories?tags=true" > .gitlab-ci/.container-registry-contents.json
- cat .gitlab-ci/.container-registry-contents.json
- IMAGE_EXISTS=`grep \""${REGISTRY_DESTINATION}"\" .gitlab-ci/.container-registry-contents.json || :`
- echo "${IMAGE_EXISTS}"
- test "${CI_JOB_MANUAL}" = true && echo "Force rebuilding container."
- >
if [ -z "${IMAGE_EXISTS}" -o "${CI_JOB_MANUAL}" = true ] ; then
echo "Building image ${REGISTRY_DESTINATION}..."
buildah bud -t ${IMAGE_TAG} --build-arg PROJECT_DIR=${CI_PROJECT_DIR} --build-arg MOUNT_DIR=/mnt/${CI_PROJECT_DIR} --volume ${CI_PROJECT_DIR}:/mnt/${CI_PROJECT_DIR} --file docker/${IMAGE_TYPE}/Dockerfile
buildah push --creds "${CI_REGISTRY_USER}:${CI_JOB_TOKEN}" ${IMAGE_TAG} ${REGISTRY_DESTINATION}
else
echo "Image ${IMAGE_TAG} already exists in the container registry. Skipping build."
fi
rules:
- if: $CI_MERGE_REQUEST_ID
when: never
- when: always
setup:containers:frontend:wait: &setup-container-wait
stage: setup
needs:
- setup:dynamic
before_script: *container-before
variables:
GIT_STRATEGY: none
IMAGE_TYPE: frontend
script:
- apt-get -y update && apt-get -y install curl
- >
while ! curl --request GET --header "PRIVATE-TOKEN:${REGISTRY_AUTH_TOKEN}" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/registry/repositories?tags=true" | grep \""${REGISTRY_DESTINATION}"\" ; do
echo "Waiting for container ${IMAGE_TAG} to appear in the container registry..."
sleep 5
done
- echo "Image ${IMAGE_TAG} has been found in the container registry. Proceeding with the pipeline."
rules:
- if: $CI_MERGE_REQUEST_ID
when: always
- when: never
retry: 0
interruptible: true
timeout: 3h
setup:containers:backend:
<<: *setup-container
variables:
IMAGE_TYPE: backend
setup:containers:backend:wait:
<<: *setup-container-wait
variables:
GIT_STRATEGY: none
IMAGE_TYPE: backend
frontend:
stage: frontend
variables:
GIT_STRATEGY: clone
needs:
- setup:dynamic
- job: setup:containers:frontend
optional: true
trigger:
strategy: depend
include:
- artifact: frontend.yml
job: setup:dynamic
backend:dev: &backend
stage: backend
variables:
GIT_STRATEGY: clone
needs:
- setup:dynamic
- job: setup:containers:backend
optional: true
- frontend
trigger:
strategy: depend
include:
- artifact: backend.yml
job: setup:dynamic
backend:prod:
<<: *backend
variables:
PROD_BUILD: -prod
release:changelog:
stage: release
rules: &release-rules
- if: $CI_COMMIT_TAG =~ /^v[0-9\.]+$/
- if: $CI_COMMIT_TAG =~ /^v[0-9\.]+-test-.*$/
script:
- echo "Preparing release..."
- ./.gitlab-ci/version.pl > .current-version
- echo "VERSION=$(cat .current-version)" >> build.env
- ./.gitlab-ci/version.pl -changelog CHANGELOG.md
artifacts:
reports:
dotenv: build.env
paths:
- .current-version
- .changelog.md
name: "changelog-${CI_COMMIT_SHORT_SHA}"
expire_in: "1 day"
release:container:
stage: release
rules: *release-rules
variables:
GIT_STRATEGY: none
image: ${IMAGE_BUILDER}
script:
- echo "Building container for release ${VERSION}..."
- buildah bud --tag fradrive:${VERSION} --file docker/fradrive/Dockerfile
- buildah add --chown uniworx:uniworx bin/uniworx /bin/uniworx
- echo "Pushing container ${VERSION} to container registry..."
- buildah push --creds "${CI_REGISTRY_USER}:${CI_JOB_TOKEN}" fradrive:${VERSION} ${CI_REGISTRY_IMAGE}/fradrive:${VERSION}
needs:
- frontend # sanity
- backend:prod # sanity
- release:changelog
release:release:
stage: release
rules: *release-rules
variables:
GIT_STRATEGY: none
image: registry.gitlab.com/gitlab-org/release-cli:latest
script:
- echo "Creating release ${VERSION}"
release:
name: "${VERSION}"
tag_name: "{$CI_COMMIT_TAG}"
description: .changelog.md
needs:
- frontend # sanity
- backend:prod # sanity
- release:changelog
- release:container
retry: 0
# frontend dependencies:
# stage: setup
# cache:
# - &npm-cache
# key: default-npm
# paths: &npm-paths
# - node_modules/
# - .npm/
# - .npmrc
# script:
# - make node_modules
# artifacts:
# paths: *npm-paths
# well-known:
# stage: setup
# script:
# - make well-known
# needs:
# - job: frontend dependencies
# artifacts: true
# cache:
# - &frontend-cache
# key: default-frontend
# paths:
# - .well-known-cache
# artifacts:
# paths:
# - well-known/
# - .well-known-cache/
# # TODO: cache is always uploaded even if up-to-date; prevent re-upload when up-to-date
# backend dependencies:
# stage: setup
# cache:
# - &stack-cache
# key: default-stack
# paths:
# - .stack/
# - .stack-work/
# script:
# - make backend-dependencies-prod
# artifacts:
# paths:
# - .stack/
# - .stack-work/
# frontend build:
# stage: build
# cache:
# - *frontend-cache
# script:
# - make frontend-build
# needs:
# - job: frontend dependencies
# artifacts: true
# - job: well-known
# artifacts: true
# artifacts:
# paths:
# - static/
# - config/webpack.yml
# # TODO: .stack-work cache not working
# backend build:
# stage: build
# cache:
# - *stack-cache
# script:
# - make bin/uniworx
# # - find .stack-work
# # - cp $(stack path --dist-dir)/build/hlint/hlint bin/test-hlint
# # - cp $(stack path --dist-dir)/build/yesod/yesod bin/test-yesod
# needs:
# - job: frontend dependencies # transitive
# artifacts: false
# - job: well-known
# artifacts: true
# - job: backend dependencies
# artifacts: true
# - job: frontend build
# artifacts: true
# artifacts:
# paths:
# - bin/
# resource_group: ram
# # TODO: part of backend build; probably deprecated
# # uniworxdb:
# # stage: build
# # script:
# # - make bin/uniworxdb
# # needs:
# # # TODO: no frontend needed
# # - job: frontend dependencies # transitive
# # artifacts: false
# # - job: frontend build # transitive
# # artifacts: false
# # artifacts:
# # paths:
# # - bin/uniworxdb
# # TODO: part of backend build; probably deprecated
# # TODO: rewrite
# # uniworx:exe:uniworxload:
# # stage: build
# # script:
# # - xzcat uniworx:lib:uniworx.nar.xz | nix-store --import
# # - nix -L build -o result ".#uniworx:exe:uniworxload"
# # - nix-store --export $(nix-store -qR result) | xz -T0 -2 > uniworx:exe:uniworxload.nar.xz
# # needs:
# # - job: frontend dependencies # transitive
# # artifacts: false
# # - job: frontend build # transitive
# # artifacts: false
# # artifacts:
# # paths:
# # - uniworx:exe:uniworxload.nar.xz
# frontend lint:
# stage: lint
# script:
# - make frontend-lint
# cache:
# - *frontend-cache
# needs:
# - job: frontend dependencies
# artifacts: true
# - job: well-known # TODO: is this really needed?
# artifacts: true
# backend lint:
# stage: lint
# cache:
# - *stack-cache
# script:
# # TODO: - make backend-lint-dev
# - make backend-lint-prod
# needs:
# - job: backend dependencies
# artifacts: true
# - job: backend build
# artifacts: true
# - job: frontend build
# artifacts: true
# - job: well-known
# artifacts: true
# frontend test:
# stage: test
# script:
# - make frontend-test
# cache: *frontend-cache
# needs:
# - job: frontend dependencies
# artifacts: true
# # TODO: configure report artifacts
# backend test:
# stage: test
# script:
# - make backend-test-prod
# cache: *stack-cache
# needs:
# - job: well-known
# artifacts: true
# - job: frontend build
# artifacts: true
# - job: backend dependencies
# artifacts: true
# - job: backend build
# artifacts: true
# # TODO: configure report artifacts
# # TODO: unify prod and test versions
# # TODO: rewrite
# container:
# stage: container
# script:
# - xzcat uniworx:exe:uniworx.nar.xz | nix-store --import
# - cp -pr --reflink=auto -L $(nix build --print-out-paths ".#uniworxDocker") uniworx.tar.gz
# needs:
# - job: frontend dependencies # transitive
# artifacts: false
# - job: frontend build # transitive
# artifacts: false
# - job: frontend test # sanity
# artifacts: false
# - job: backend test # sanity
# artifacts: false
# artifacts:
# paths:
# - uniworx.tar.gz
# rules: &release-rules
# - if: $CI_COMMIT_TAG =~ /^v/
# # TODO: rewrite
# test container:
# stage: container
# script:
# - xzcat uniworx:exe:uniworx.nar.xz | nix-store --import
# - cp -pr --reflink=auto -L $(nix build --print-out-paths ".#uniworxTestDocker") uniworx.tar.gz
# needs:
# - job: frontend dependencies # transitive
# artifacts: false
# - job: frontend build # transitive
# artifacts: false
# - job: frontend test # sanity
# artifacts: false
# - job: backend test # sanity
# artifacts: false
# artifacts:
# paths:
# - uniworx.tar.gz
# rules: &test-release-rules
# - if: $CI_COMMIT_TAG =~ /^t/
# # TODO: unify prod and test versions
# # TODO: rewrite
# parse changelog:
# stage: prepare release
# needs:
# - job: frontend dependencies
# artifacts: true
# rules: *release-rules
# script:
# - xzcat node-dependencies.nar.xz | nix-store --import
# - nix -L run ".#jqChangelogJson" -- -r '.versions[0].version' > .current-version
# - nix -L run ".#jqChangelogJson" -- -r '.versions[0].body' > .current-changelog.md
# - echo "VERSION=$(cat .current-version)" >> build.env
# artifacts:
# reports:
# dotenv: build.env
# paths:
# - .current-version
# - .current-changelog.md
# name: "changelog-${CI_COMMIT_SHORT_SHA}"
# expire_in: "1 day"
# # TODO: rewrite
# parse test changelog:
# stage: prepare release
# needs:
# - job: frontend dependencies
# artifacts: true
# rules: *test-release-rules
# script:
# - xzcat node-dependencies.nar.xz | nix-store --import
# - nix -L run ".#jqChangelogJson" -- -r '.versions[0].version' > .current-version
# - nix -L run ".#jqChangelogJson" -- -r '.versions[0].body' > .current-changelog.md
# - echo "VERSION=$(cat .current-version)" >> build.env
# artifacts:
# reports:
# dotenv: build.env
# paths:
# - .current-version
# - .current-changelog.md
# name: "changelog-${CI_COMMIT_SHORT_SHA}"
# # TODO: unify prod and test versions
# # TODO: rewrite
# upload container:
# variables:
# GIT_STRATEGY: none
# stage: release
# image: quay.io/skopeo/stable:latest
# script:
# - skopeo --insecure-policy copy --dest-creds "${CI_REGISTRY_USER}:${CI_JOB_TOKEN}" docker-archive://$(pwd)/uniworx.tar.gz docker://${CI_REGISTRY_IMAGE}:${VERSION}
# - skopeo --insecure-policy copy --src-creds "${CI_REGISTRY_USER}:${CI_JOB_TOKEN}" --dest-creds "${CI_REGISTRY_USER}:${CI_JOB_TOKEN}" docker://${CI_REGISTRY_IMAGE}:${VERSION} docker://${CI_REGISTRY_IMAGE}:latest
# needs:
# - job: frontend dependencies # transitive
# artifacts: false
# - job: frontend build # transitive
# artifacts: false
# - job: container
# artifacts: true
# - job: parse changelog
# artifacts: true
# - job: frontend test # sanity
# artifacts: false
# - job: backend test # sanity
# artifacts: false
# rules: *release-rules
# # TODO: rewrite
# upload test container:
# variables:
# GIT_STRATEGY: none
# stage: release
# image: quay.io/skopeo/stable:latest
# script:
# - skopeo --insecure-policy copy --dest-creds "${CI_REGISTRY_USER}:${CI_JOB_TOKEN}" docker-archive://$(pwd)/uniworx.tar.gz docker://${CI_REGISTRY}/fradrive/fradrive/test:${CI_COMMIT_REF_NAME}
# - skopeo --insecure-policy copy --src-creds "${CI_REGISTRY_USER}:${CI_JOB_TOKEN}" --dest-creds "${CI_REGISTRY_USER}:${CI_JOB_TOKEN}" docker://${CI_REGISTRY}/fradrive/fradrive/test:${CI_COMMIT_REF_NAME} docker://${CI_REGISTRY}/fradrive/fradrive/test:latest
# needs:
# - job: frontend dependencies # transitive
# artifacts: false
# - job: frontend build # transitive
# artifacts: false
# - job: test container
# artifacts: true
# - job: parse test changelog
# artifacts: true
# - job: frontend test # sanity
# artifacts: false
# - job: backend test # sanity
# artifacts: false
# rules: *test-release-rules
# # TODO: unify prod and test versions
# # TODO: rewrite
# release:
# variables:
# GIT_STRATEGY: none
# stage: release
# image: registry.gitlab.com/gitlab-org/release-cli:latest
# rules: *release-rules
# script:
# - echo "Will create release ${VERSION}..."
# release:
# name: '$VERSION'
# tag_name: '$CI_COMMIT_TAG'
# description: .current-changelog.md
# needs:
# - job: frontend test # sanity
# artifacts: false
# - job: backend test # sanity
# artifacts: false
# - job: parse changelog
# artifacts: true
# retry: 0
# # TODO: rewrite
# test release:
# variables:
# GIT_STRATEGY: none
# stage: release
# image: registry.gitlab.com/gitlab-org/release-cli:latest
# rules: *test-release-rules
# script:
# - echo "Will create test release ${VERSION}-test..."
# release:
# name: "${VERSION}-test"
# tag_name: '$CI_COMMIT_TAG'
# description: .current-changelog.md
# needs:
# - job: frontend test # sanity
# artifacts: false
# - job: backend test # sanity
# artifacts: false
# - job: parse test changelog
# artifacts: true
# retry: 0