diff --git a/.gitignore b/.gitignore index 687a125..831f9df 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,6 @@ config.edn build-and-move-frontend.sh website.yaml + +out.yaml +.eastwood diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 820efbd..83998da 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,11 +5,18 @@ stages: - upload - image -services: - - docker:dind +.img: &img + image: "domaindrivenarchitecture/ddadevops-dind:4.7.2" + services: + - docker:dind + before_script: + - export RELEASE_ARTIFACT_TOKEN=$MEISSA_REPO_BUERO_RW + - export IMAGE_DOCKERHUB_USER=$DOCKERHUB_USER + - export IMAGE_DOCKERHUB_PASSWORD=$DOCKERHUB_PASSWORD + - export IMAGE_TAG=$CI_COMMIT_TAG .cljs-job: &cljs - image: domaindrivenarchitecture/shadow-cljs + image: "domaindrivenarchitecture/ddadevops-clj-cljs:4.7.2" cache: key: ${CI_COMMIT_REF_SLUG} paths: @@ -17,40 +24,45 @@ services: - .shadow-cljs/ - .m2 before_script: - - echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc - - npm install + - export RELEASE_ARTIFACT_TOKEN=$MEISSA_REPO_BUERO_RW + - echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc + - npm install -.clj-uploadjob: &clj - image: domaindrivenarchitecture/lein +.clj-job: &clj + image: "domaindrivenarchitecture/ddadevops-clj-cljs:4.7.2" cache: key: ${CI_COMMIT_REF_SLUG} paths: - .m2 before_script: - - mkdir -p /root/.lein - - echo "{:auth {:repository-auth {#\"clojars\" {:username \"${CLOJARS_USER}\" :password \"${CLOJARS_TOKEN_DOMAINDRIVENARCHITECTURE}\" }}}}" > ~/.lein/profiles.clj + - export RELEASE_ARTIFACT_TOKEN=$MEISSA_REPO_BUERO_RW + - mkdir -p /root/.lein + - echo "{:auth {:repository-auth {#\"clojars\" {:username \"${CLOJARS_USER}\" :password \"${CLOJARS_TOKEN_DOMAINDRIVENARCHITECTURE}\" }}}}" > ~/.lein/profiles.clj -test-cljs: - <<: *cljs - stage: build_and_test - script: - - shadow-cljs compile test - - node target/node-tests.js +.tag_only: &tag_only + rules: + - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' + when: never + - if: '$CI_COMMIT_TAG =~ /^[0-9]+\.[0-9]+\.[0-9]+$/' test-clj: <<: *clj stage: build_and_test script: - - lein test + - pyb test_clj + +test-cljs: + <<: *cljs + stage: build_and_test + script: + - pyb test_cljs test-schema: <<: *clj stage: build_and_test script: - - lein uberjar - - java -jar target/uberjar/c4k-website-standalone.jar src/test/resources/website-test/valid-config.yaml src/test/resources/website-test/valid-auth.yaml | kubeconform --kubernetes-version 1.23.0 --strict --skip Certificate - + - pyb test_schema artifacts: - expire_in: 1h paths: - target/uberjar @@ -58,10 +70,8 @@ report-frontend: <<: *cljs stage: package script: - - mkdir -p target/frontend-build - - shadow-cljs run shadow.cljs.build-report frontend target/frontend-build/build-report.html + - pyb report_frontend artifacts: - expire_in: 1h paths: - target/frontend-build/build-report.html @@ -69,13 +79,8 @@ package-frontend: <<: *cljs stage: package script: - - mkdir -p target/frontend-build - - shadow-cljs release frontend - - cp public/js/main.js target/frontend-build/c4k-website.js - - sha256sum target/frontend-build/c4k-website.js > target/frontend-build/c4k-website.js.sha256 - - sha512sum target/frontend-build/c4k-website.js > target/frontend-build/c4k-website.js.sha512 + - pyb package_frontend artifacts: - expire_in: 1h paths: - target/frontend-build @@ -83,47 +88,28 @@ package-uberjar: <<: *clj stage: package script: - - lein uberjar - - sha256sum target/uberjar/c4k-website-standalone.jar > target/uberjar/c4k-website-standalone.jar.sha256 - - sha512sum target/uberjar/c4k-website-standalone.jar > target/uberjar/c4k-website-standalone.jar.sha512 + - pyb package_uberjar artifacts: - expire_in: 1h - paths: - - target/uberjar - -upload-clj-release: - <<: *clj - stage: upload - rules: - - if: '$CI_COMMIT_TAG != null' - script: - - lein deploy - -release: - image: registry.gitlab.com/gitlab-org/release-cli:latest - stage: upload - rules: - - if: '$CI_COMMIT_TAG != null' - artifacts: - expire_in: 24h paths: - target/uberjar - - target/frontend-build - script: - - apk --no-cache add curl - - | - release-cli create --name "Release $CI_COMMIT_TAG" --tag-name $CI_COMMIT_TAG \ - --assets-link "{\"name\":\"c4k-website-standalone.jar\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-website/-/jobs/${CI_JOB_ID}/artifacts/file/target/uberjar/c4k-website-standalone.jar\"}" \ - --assets-link "{\"name\":\"c4k-website-standalone.jar.sha256\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-website/-/jobs/${CI_JOB_ID}/artifacts/file/target/uberjar/c4k-website-standalone.jar.sha256\"}" \ - --assets-link "{\"name\":\"c4k-website-standalone.jar.sha512\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-website/-/jobs/${CI_JOB_ID}/artifacts/file/target/uberjar/c4k-website-standalone.jar.sha512\"}" \ - --assets-link "{\"name\":\"c4k-website.js\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-website/-/jobs/${CI_JOB_ID}/artifacts/file/target/frontend-build/c4k-website.js\"}" \ - --assets-link "{\"name\":\"c4k-website.js.sha256\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-website/-/jobs/${CI_JOB_ID}/artifacts/file/target/frontend-build/c4k-website.js.sha256\"}" \ - --assets-link "{\"name\":\"c4k-website.js.sha512\",\"url\":\"https://gitlab.com/domaindrivenarchitecture/c4k-website/-/jobs/${CI_JOB_ID}/artifacts/file/target/frontend-build/c4k-website.js.sha512\"}" \ -website-image-test-publish: - image: domaindrivenarchitecture/devops-build:latest - stage: image - rules: - - if: '$CI_COMMIT_TAG != null' +release-to-clojars: + <<: *clj + <<: *tag_only + stage: upload script: - - cd infrastructure/c4k-website-build && pyb image test publish \ No newline at end of file + - pyb upload_clj + +release-to-forgejo: + <<: *clj + <<: *tag_only + stage: upload + script: + - pyb publish_artifacts + +website-image-publish: + <<: *img + <<: *tag_only + stage: image + script: + - cd infrastructure/build && pyb image publish \ No newline at end of file diff --git a/build.py b/build.py new file mode 100644 index 0000000..8ba25a1 --- /dev/null +++ b/build.py @@ -0,0 +1,178 @@ +from os import environ +from subprocess import run +from pybuilder.core import init, task +from ddadevops import * + +default_task = "dev" + +name = "c4k-website" +MODULE = "not-used" +PROJECT_ROOT_PATH = "." + + +@init +def initialize(project): + input = { + "name": name, + "module": MODULE, + "stage": "notused", + "project_root_path": PROJECT_ROOT_PATH, + "build_types": [], + "mixin_types": ["RELEASE"], + "release_primary_build_file": "project.clj", + "release_secondary_build_files": [ + "package.json", + "infrastructure/build/build.py", + ], + "release_artifact_server_url": "https://repo.prod.meissa.de", + "release_organisation": "meissa", + "release_repository_name": name, + "release_artifacts": [ + "target/uberjar/c4k-website-standalone.jar", + "target/frontend-build/c4k-website.js", + ], + } + + build = ReleaseMixin(project, input) + build.initialize_build_dir() + + +@task +def test_clj(project): + run("lein test", shell=True, check=True) + + +@task +def test_cljs(project): + run("shadow-cljs compile test", shell=True, check=True) + run("node target/node-tests.js", shell=True, check=True) + + +@task +def test_schema(project): + run("lein uberjar", shell=True, check=True) + run( + "java -jar target/uberjar/c4k-website-standalone.jar " + + "src/test/resources/website-test/valid-config.yaml " + + "src/test/resources/website-test/valid-auth.yaml | " + + "kubeconform --kubernetes-version 1.23.0 --strict --skip Certificate -", + shell=True, + check=True, + ) + + +@task +def report_frontend(project): + run("mkdir -p target/frontend-build", shell=True, check=True) + run( + "shadow-cljs run shadow.cljs.build-report frontend target/frontend-build/build-report.html", + shell=True, + check=True, + ) + + +@task +def package_frontend(project): + run("mkdir -p target/frontend-build", shell=True, check=True) + run("shadow-cljs release frontend", shell=True, check=True) + run( + "cp public/js/main.js target/frontend-build/c4k-website.js", + shell=True, + check=True, + ) + run( + "sha256sum target/frontend-build/c4k-website.js > target/frontend-build/c4k-website.js.sha256", + shell=True, + check=True, + ) + run( + "sha512sum target/frontend-build/c4k-website.js > target/frontend-build/c4k-website.js.sha512", + shell=True, + check=True, + ) + + +@task +def package_uberjar(project): + run( + "sha256sum target/uberjar/c4k-website-standalone.jar > target/uberjar/c4k-website-standalone.jar.sha256", + shell=True, + check=True, + ) + run( + "sha512sum target/uberjar/c4k-website-standalone.jar > target/uberjar/c4k-website-standalone.jar.sha512", + shell=True, + check=True, + ) + + +@task +def upload_clj(project): + run("lein deploy", shell=True, check=True) + + +@task +def lint(project): + run( + "lein eastwood", + shell=True, + check=True, + ) + run( + "lein ancient check", + shell=True, + check=True, + ) + + +@task +def patch(project): + linttest(project, "PATCH") + release(project) + + +@task +def minor(project): + linttest(project, "MINOR") + release(project) + + +@task +def major(project): + linttest(project, "MAJOR") + release(project) + + +@task +def dev(project): + linttest(project, "NONE") + + +@task +def prepare(project): + build = get_devops_build(project) + build.prepare_release() + + +@task +def tag(project): + build = get_devops_build(project) + build.tag_bump_and_push_release() + +@task +def publish_artifacts(project): + build = get_devops_build(project) + build.publish_artifacts() + +def release(project): + prepare(project) + tag(project) + + +def linttest(project, release_type): + build = get_devops_build(project) + build.update_release_type(release_type) + test_clj(project) + test_cljs(project) + test_schema(project) + lint(project) diff --git a/infrastructure/build/build.py b/infrastructure/build/build.py new file mode 100644 index 0000000..63d630a --- /dev/null +++ b/infrastructure/build/build.py @@ -0,0 +1,58 @@ +from os import environ +from datetime import datetime +from pybuilder.core import task, init +from ddadevops import * +import logging + +name = 'c4k-website' +MODULE = 'build' +PROJECT_ROOT_PATH = '../..' +version = "1.1.4-SNAPSHOT" + + +@init +def initialize(project): + image_tag = version + if "dev" in image_tag: + image_tag += datetime.now().strftime("%Y-%m-%d-%H-%M-%S") + + input = { + "name": name, + "module": MODULE, + "stage": "notused", + "project_root_path": PROJECT_ROOT_PATH, + "build_types": ["IMAGE"], + "mixin_types": [], + "image_naming": "NAME_AND_MODULE", + "image_tag": f"{image_tag}", + } + + project.build_depends_on("ddadevops>=4.7.0") + + build = DevopsImageBuild(project, input) + build.initialize_build_dir() + + +@task +def image(project): + build = get_devops_build(project) + build.image() + + +@task +def drun(project): + build = get_devops_build(project) + build.drun() + + +@task +def test(project): + build = get_devops_build(project) + build.test() + + +@task +def publish(project): + build = get_devops_build(project) + build.dockerhub_login() + build.dockerhub_publish() diff --git a/infrastructure/c4k-website-build/image/Dockerfile b/infrastructure/build/image/Dockerfile similarity index 100% rename from infrastructure/c4k-website-build/image/Dockerfile rename to infrastructure/build/image/Dockerfile diff --git a/infrastructure/c4k-website-build/image/resources/entrypoint.sh b/infrastructure/build/image/resources/entrypoint.sh similarity index 100% rename from infrastructure/c4k-website-build/image/resources/entrypoint.sh rename to infrastructure/build/image/resources/entrypoint.sh diff --git a/infrastructure/c4k-website-build/image/resources/exclude.pattern b/infrastructure/build/image/resources/exclude.pattern similarity index 100% rename from infrastructure/c4k-website-build/image/resources/exclude.pattern rename to infrastructure/build/image/resources/exclude.pattern diff --git a/infrastructure/c4k-website-build/image/resources/functions.sh b/infrastructure/build/image/resources/functions.sh similarity index 100% rename from infrastructure/c4k-website-build/image/resources/functions.sh rename to infrastructure/build/image/resources/functions.sh diff --git a/infrastructure/c4k-website-build/image/resources/install.sh b/infrastructure/build/image/resources/install.sh similarity index 100% rename from infrastructure/c4k-website-build/image/resources/install.sh rename to infrastructure/build/image/resources/install.sh diff --git a/infrastructure/c4k-website-build/image/resources/project.clj b/infrastructure/build/image/resources/project.clj similarity index 100% rename from infrastructure/c4k-website-build/image/resources/project.clj rename to infrastructure/build/image/resources/project.clj diff --git a/infrastructure/c4k-website-build/test/Dockerfile b/infrastructure/build/test/Dockerfile similarity index 93% rename from infrastructure/c4k-website-build/test/Dockerfile rename to infrastructure/build/test/Dockerfile index 41aadf5..4b44c96 100644 --- a/infrastructure/c4k-website-build/test/Dockerfile +++ b/infrastructure/build/test/Dockerfile @@ -3,6 +3,7 @@ FROM c4k-website-build RUN apt update RUN apt -yqq --no-install-recommends --yes install curl default-jre-headless +# TODO: path does not exist RUN curl -L -o /tmp/serverspec.jar \ https://github.com/DomainDrivenArchitecture/dda-serverspec-crate/releases/download/2.0.0/dda-serverspec-standalone.jar diff --git a/infrastructure/c4k-website-build/test/serverspec.edn b/infrastructure/build/test/serverspec.edn similarity index 100% rename from infrastructure/c4k-website-build/test/serverspec.edn rename to infrastructure/build/test/serverspec.edn diff --git a/infrastructure/c4k-website-build/build.py b/infrastructure/c4k-website-build/build.py deleted file mode 100644 index b42b47c..0000000 --- a/infrastructure/c4k-website-build/build.py +++ /dev/null @@ -1,51 +0,0 @@ -from os import environ -from pybuilder.core import task, init -from ddadevops import * -import logging - -name = 'c4k-website-build' -MODULE = 'docker' -PROJECT_ROOT_PATH = '../..' - -class MyBuild(DevopsDockerBuild): - pass - -@init -def initialize(project): - project.build_depends_on('ddadevops>=0.12.4') - stage = 'prod' - dockerhub_user = environ.get('DOCKERHUB_USER') - if not dockerhub_user: - dockerhub_user = gopass_field_from_path('meissa/web/docker.com', 'login') - dockerhub_password = environ.get('DOCKERHUB_PASSWORD') - if not dockerhub_password: - dockerhub_password = gopass_password_from_path('meissa/web/docker.com') - tag = environ.get('CI_COMMIT_TAG') - if not tag: - tag = get_tag_from_latest_commit() - config = create_devops_docker_build_config( - stage, PROJECT_ROOT_PATH, MODULE, dockerhub_user, dockerhub_password, docker_publish_tag=tag) - build = MyBuild(project, config) - build.initialize_build_dir() - - -@task -def image(project): - build = get_devops_build(project) - build.image() - -@task -def drun(project): - build = get_devops_build(project) - build.drun() - -@task -def publish(project): - build = get_devops_build(project) - build.dockerhub_login() - build.dockerhub_publish() - -@task -def test(project): - build = get_devops_build(project) - build.test() diff --git a/project.clj b/project.clj index 46520e7..acf5607 100644 --- a/project.clj +++ b/project.clj @@ -5,7 +5,7 @@ :url "https://www.apache.org/licenses/LICENSE-2.0.html"} :dependencies [[org.clojure/clojure "1.11.1"] [org.clojure/tools.reader "1.3.6"] - [org.domaindrivenarchitecture/c4k-common-clj "6.0.1"] + [org.domaindrivenarchitecture/c4k-common-clj "6.0.3"] [hickory "0.7.1" :exclusions [viebel/codox-klipse-theme]]] :target-path "target/%s/" :source-paths ["src/main/cljc" @@ -22,10 +22,10 @@ :uberjar {:aot :all :main dda.c4k-website.uberjar :uberjar-name "c4k-website-standalone.jar" - :dependencies [[org.clojure/tools.cli "1.0.214"] - [ch.qos.logback/logback-classic "1.4.5" + :dependencies [[org.clojure/tools.cli "1.0.219"] + [ch.qos.logback/logback-classic "1.4.11" :exclusions [com.sun.mail/javax.mail]] - [org.slf4j/jcl-over-slf4j "2.0.6"]]}} + [org.slf4j/jcl-over-slf4j "2.0.9"]]}} :release-tasks [["test"] ["vcs" "assert-committed"] ["change" "version" "leiningen.release/bump-version" "release"]