From 5cb42ffd6fcb08e708935f82f95c938bdd51f639 Mon Sep 17 00:00:00 2001 From: James Harton Date: Fri, 26 Jul 2024 21:45:37 +1200 Subject: [PATCH] chore: add CI configuration. --- .dialyzer_ignore.exs | 3 + .doctor.exs | 16 ++ .drone.yml | 359 +++++++++++++++++++++++++++++++++++++++++++ mix.exs | 3 + 4 files changed, 381 insertions(+) create mode 100644 .dialyzer_ignore.exs create mode 100644 .doctor.exs create mode 100644 .drone.yml diff --git a/.dialyzer_ignore.exs b/.dialyzer_ignore.exs new file mode 100644 index 0000000..e74574b --- /dev/null +++ b/.dialyzer_ignore.exs @@ -0,0 +1,3 @@ +[ + ~r/test\/support.*/ +] diff --git a/.doctor.exs b/.doctor.exs new file mode 100644 index 0000000..6efd0d1 --- /dev/null +++ b/.doctor.exs @@ -0,0 +1,16 @@ +%Doctor.Config{ + ignore_modules: [], + ignore_paths: [ + "test/support/factory.ex" + ], + min_module_doc_coverage: 40, + min_module_spec_coverage: 0, + min_overall_doc_coverage: 50, + min_overall_spec_coverage: 0, + min_overall_moduledoc_coverage: 100, + exception_moduledoc_required: true, + raise: false, + reporter: Doctor.Reporters.Full, + struct_type_spec_required: true, + umbrella: false +} diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..6d2bfc8 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,359 @@ +kind: pipeline +type: docker +name: build + +steps: +- name: restore ASDF cache + image: meltwater/drone-cache + pull: "always" + environment: + AWS_ACCESS_KEY_ID: + from_secret: ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY: + from_secret: SECRET_ACCESS_KEY + AWS_PLUGIN_PATH_STYLE: true + settings: + restore: true + endpoint: + from_secret: S3_ENDPOINT + bucket: + from_secret: CACHE_BUCKET + region: us-east-1 + path-style: true + cache_key: 'asdf-{{ os }}-{{ arch }}-{{ checksum ".tool-versions" }}' + mount: + - .asdf + +- name: restore build cache + image: meltwater/drone-cache + environment: + AWS_ACCESS_KEY_ID: + from_secret: ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY: + from_secret: SECRET_ACCESS_KEY + AWS_PLUGIN_PATH_STYLE: true + settings: + restore: true + endpoint: + from_secret: S3_ENDPOINT + bucket: + from_secret: CACHE_BUCKET + region: us-east-1 + path-style: true + cache_key: 'elixir-{{ checksum "mix.lock" }}-{{ checksum ".tool-versions" }}' + mount: + - deps + - _build + - .hex + - .mix + - .rebar3 + +- name: install dependencies + image: harton.dev/james/asdf_container:latest + pull: "always" + environment: + MIX_ENV: test + HEX_HOME: /drone/src/.hex + MIX_HOME: /drone/src/.mix + REBAR_BASE_DIR: /drone/src/.rebar3 + ASDF_DATA_DIR: /drone/src/.asdf + ASDF_DIR: /root/.asdf + depends_on: + - restore ASDF cache + - restore build cache + commands: + - asdf_install + - rm -rf .asdf/downloads + - . $ASDF_DIR/asdf.sh + - mix local.hex --if-missing --force + - mix local.rebar --if-missing --force + - mix deps.get + - mix deps.compile + - mix dialyzer --plt + +- name: store ASDF cache + image: meltwater/drone-cache + environment: + AWS_ACCESS_KEY_ID: + from_secret: ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY: + from_secret: SECRET_ACCESS_KEY + AWS_PLUGIN_PATH_STYLE: true + depends_on: + - install dependencies + settings: + rebuild: true + override: false + endpoint: + from_secret: S3_ENDPOINT + bucket: + from_secret: CACHE_BUCKET + region: us-east-1 + path-style: true + cache_key: 'asdf-{{ os }}-{{ arch }}-{{ checksum ".tool-versions" }}' + mount: + - .asdf + +- name: store build cache + image: meltwater/drone-cache + environment: + AWS_ACCESS_KEY_ID: + from_secret: ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY: + from_secret: SECRET_ACCESS_KEY + AWS_PLUGIN_PATH_STYLE: true + depends_on: + - install dependencies + settings: + rebuild: true + override: false + endpoint: + from_secret: S3_ENDPOINT + bucket: + from_secret: CACHE_BUCKET + region: us-east-1 + path-style: true + cache_key: 'elixir-{{ checksum "mix.lock" }}-{{ checksum ".tool-versions" }}' + mount: + - deps + - _build + - .hex + - .mix + - .rebar3 + +- name: mix compile + image: harton.dev/james/asdf_container:latest + environment: + MIX_ENV: test + HEX_HOME: /drone/src/.hex + MIX_HOME: /drone/src/.mix + REBAR_BASE_DIR: /drone/src/.rebar3 + ASDF_DATA_DIR: /drone/src/.asdf + depends_on: + - install dependencies + commands: + - asdf mix compile --warnings-as-errors + +- name: mix test + image: harton.dev/james/asdf_container:latest + environment: + MIX_ENV: test + HEX_HOME: /drone/src/.hex + MIX_HOME: /drone/src/.mix + REBAR_BASE_DIR: /drone/src/.rebar3 + ASDF_DATA_DIR: /drone/src/.asdf + depends_on: + - mix compile + commands: + - asdf mix test + +- name: mix credo + image: harton.dev/james/asdf_container:latest + environment: + MIX_ENV: test + HEX_HOME: /drone/src/.hex + MIX_HOME: /drone/src/.mix + REBAR_BASE_DIR: /drone/src/.rebar3 + ASDF_DATA_DIR: /drone/src/.asdf + depends_on: + - mix compile + commands: + - asdf mix credo --strict + +- name: mix dialyzer + image: harton.dev/james/asdf_container:latest + environment: + MIX_ENV: test + HEX_HOME: /drone/src/.hex + MIX_HOME: /drone/src/.mix + REBAR_BASE_DIR: /drone/src/.rebar3 + ASDF_DATA_DIR: /drone/src/.asdf + depends_on: + - mix compile + commands: + - asdf mix dialyzer + +- name: mix hex.audit + image: harton.dev/james/asdf_container:latest + environment: + MIX_ENV: test + HEX_HOME: /drone/src/.hex + MIX_HOME: /drone/src/.mix + REBAR_BASE_DIR: /drone/src/.rebar3 + ASDF_DATA_DIR: /drone/src/.asdf + depends_on: + - mix compile + commands: + - asdf mix hex.audit + +- name: mix format + image: harton.dev/james/asdf_container:latest + environment: + MIX_ENV: test + HEX_HOME: /drone/src/.hex + MIX_HOME: /drone/src/.mix + REBAR_BASE_DIR: /drone/src/.rebar3 + ASDF_DATA_DIR: /drone/src/.asdf + depends_on: + - mix compile + commands: + - asdf mix format --check-formatted + +- name: mix deps.unlock + image: harton.dev/james/asdf_container:latest + environment: + MIX_ENV: test + HEX_HOME: /drone/src/.hex + MIX_HOME: /drone/src/.mix + REBAR_BASE_DIR: /drone/src/.rebar3 + ASDF_DATA_DIR: /drone/src/.asdf + depends_on: + - mix compile + commands: + - asdf mix deps.unlock --check-unused + +- name: mix doctor + image: harton.dev/james/asdf_container:latest + environment: + MIX_ENV: test + HEX_HOME: /drone/src/.hex + MIX_HOME: /drone/src/.mix + REBAR_BASE_DIR: /drone/src/.rebar3 + ASDF_DATA_DIR: /drone/src/.asdf + depends_on: + - mix compile + commands: + - asdf mix doctor --full + +- name: mix git_ops.check_message + image: harton.dev/james/asdf_container:latest + environment: + MIX_ENV: test + HEX_HOME: /drone/src/.hex + MIX_HOME: /drone/src/.mix + REBAR_BASE_DIR: /drone/src/.rebar3 + ASDF_DATA_DIR: /drone/src/.asdf + depends_on: + - mix compile + commands: + - git log -1 --format=%s > .last_commit_message + - asdf mix git_ops.check_message .last_commit_message + +- name: mix git_ops.release + image: harton.dev/james/asdf_container:latest + when: + branch: + - main + event: + exclude: + - pull_request + depends_on: + - mix test + - mix credo + - mix dialyzer + - mix hex.audit + - mix format + - mix deps.unlock + - mix doctor + - mix git_ops.check_message + environment: + MIX_ENV: test + HEX_HOME: /drone/src/.hex + MIX_HOME: /drone/src/.mix + REBAR_BASE_DIR: /drone/src/.rebar3 + ASDF_DATA_DIR: /drone/src/.asdf + ASDF_DIR: /root/.asdf + DRONE_TOKEN: + from_secret: DRONE_TOKEN + commands: + - git fetch --tags + - . $ASDF_DIR/asdf.sh + - mix git_ops.project_info --format=shell > before.env + - mix git_ops.release --yes --no-major || true + - mix git_ops.project_info --format=shell > after.env + - . ./before.env + - export OLD_APP_VERSION=$${APP_VERSION} + - . ./after.env + - export NEW_APP_VERSION=$${APP_VERSION} + - if [ "v$${OLD_APP_VERSION}" != "v$${NEW_APP_VERSION}" ]; then + - export GIT_URL=$(echo $DRONE_GIT_HTTP_URL | sed -e "s/:\\/\\//:\\/\\/$DRONE_REPO_OWNER:$DRONE_TOKEN@/") + - git push $${GIT_URL} "HEAD:${DRONE_COMMIT_REF}" "refs/tags/v$${NEW_APP_VERSION}" + - fi + +- name: build artifacts + image: harton.dev/james/asdf_container:latest + when: + event: + - tag + refs: + include: + - refs/tags/v* + depends_on: + - mix test + - mix credo + - mix dialyzer + - mix hex.audit + - mix format + - mix deps.unlock + - mix doctor + - mix git_ops.check_message + environment: + MIX_ENV: test + HEX_HOME: /drone/src/.hex + MIX_HOME: /drone/src/.mix + REBAR_BASE_DIR: /drone/src/.rebar3 + ASDF_DATA_DIR: /drone/src/.asdf + ASDF_DIR: /root/.asdf + commands: + - . $ASDF_DIR/asdf.sh + - mix git_ops.project_info --format=shell > app.env + - . ./app.env + - mkdir artifacts + - mix hex.build -o "artifacts/$${APP_NAME}-$${APP_VERSION}-pkg.tar" + - gzip "artifacts/$${APP_NAME}-$${APP_VERSION}-pkg.tar" + - mix docs + - tar zcvf "artifacts/$${APP_NAME}-$${APP_VERSION}-docs.tar.gz" doc/ + - git tag -l --format='%(contents:subject)' v$${APP_VERSION} > tag_subject + - git tag -l --format='%(contents:body)' v$${APP_VERSION} > tag_body + +- name: gitea release + image: plugins/gitea-release + when: + event: + - tag + refs: + include: + - refs/tags/v* + depends_on: + - build artifacts + settings: + api_key: + from_secret: DRONE_TOKEN + base_url: https://harton.dev + files: artifacts/*.tar.gz + checksum: sha256 + title: tag_subject + note: tag_body + +- name: docs release + when: + event: + - tag + refs: + include: + - refs/tags/v* + image: minio/mc + environment: + S3_ENDPOINT: + from_secret: S3_ENDPOINT + ACCESS_KEY: + from_secret: ACCESS_KEY_ID + SECRET_KEY: + from_secret: SECRET_ACCESS_KEY + depends_on: + - build artifacts + commands: + - mc alias set store $${S3_ENDPOINT} $${ACCESS_KEY} $${SECRET_KEY} + - mc mb -p store/docs.harton.nz + - mc mirror --overwrite doc/ store/docs.harton.nz/$${DRONE_REPO}/$${DRONE_TAG} + - mc mirror --overwrite doc/ store/docs.harton.nz/$${DRONE_REPO} diff --git a/mix.exs b/mix.exs index 5bd3b5c..cfe7f05 100644 --- a/mix.exs +++ b/mix.exs @@ -22,6 +22,9 @@ defmodule Podbox.MixProject do docs: [ main: "readme", extras: ["README.md", "CHANGELOG.md"] + ], + dialyzer: [ + plt_add_apps: [:smokestack] ] ] end