From 8199f1ebf487754ded757c92c546b5efe3b55ad2 Mon Sep 17 00:00:00 2001 From: Simone Cottini Date: Thu, 30 Nov 2023 09:43:35 +0100 Subject: [PATCH] [PLATFORM-1372]: Migrate bridge.rs to GHA (#145) * Implement CI/CD with GHA * Refactor ci, cd and Makefile * Add fmt-check task in makefile.toml * Remove drone.yml * Check package version in cd * Remove build script * Add pss as codeowners --- .drone.yml | 269 ---------------------------- .github/CODEOWNERS | 2 + .github/workflows/cd.yml | 29 +++ .github/workflows/ci.yml | 37 ++++ Cargo.toml | 1 - Makefile.toml | 95 ++-------- deploy/build | 36 ---- src/lib.rs | 6 +- src/request/request_type/graphql.rs | 2 +- src/request/request_type/rest.rs | 2 +- tests/common/mod.rs | 1 - 11 files changed, 85 insertions(+), 395 deletions(-) delete mode 100644 .drone.yml create mode 100644 .github/CODEOWNERS create mode 100644 .github/workflows/cd.yml create mode 100644 .github/workflows/ci.yml delete mode 100755 deploy/build diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index e513e54..0000000 --- a/.drone.yml +++ /dev/null @@ -1,269 +0,0 @@ ---- -kind: pipeline -name: default - -platform: - os: linux - arch: amd64 - -clone: - disable: true - -steps: -- name: git-clone - image: public.ecr.aws/prima/drone-git:1.3-3 - environment: - PLUGIN_DEPTH: 5 - -- name: cache-restore - image: public.ecr.aws/prima/drone-tools:1.21.3 - commands: - - . /etc/profile.d/ecs-credentials-endpoint - - cache-restore - environment: - BUCKET_NAME: prima-ci-cache - volumes: - - name: ecs - path: /etc/profile.d/ecs-credentials-endpoint - - name: docker - path: /var/run/docker.sock - depends_on: - - git-clone - -- name: check-secrets - image: public.ecr.aws/prima/drone-tools:1.21.3 - commands: - - . /etc/profile.d/ecs-credentials-endpoint - - check-secrets-grants - volumes: - - name: ecs - path: /etc/profile.d/ecs-credentials-endpoint - depends_on: - - git-clone - -- name: check-public-docker-images - image: public.ecr.aws/prima/drone-tools:1.21.3 - commands: - - check-public-docker-images - depends_on: - - git-clone - -- name: build-image - image: public.ecr.aws/prima/drone-tools:1.21.3 - commands: - - sed -i 's/USER app/USER root/g' ./Dockerfile - - docker build -t prima/bridge.rs-ci:${DRONE_COMMIT} ./ - volumes: - - name: docker - path: /var/run/docker.sock - depends_on: - - cache-restore - -- name: cargo-deps - image: prima/bridge.rs-ci:${DRONE_COMMIT} - commands: - - cargo fetch - environment: - CARGO_HOME: /drone/src/.cargo - depends_on: - - build-image - -- name: cargo-format - image: prima/bridge.rs-ci:${DRONE_COMMIT} - commands: - - cargo make --profile drone format-ci - environment: - CARGO_HOME: /drone/src/.cargo - depends_on: - - cargo-deps - -- name: cargo-clippy-ci - image: prima/bridge.rs-ci:${DRONE_COMMIT} - commands: - - cargo make --profile drone clippy-ci - environment: - BUILD_ENV: dev - CARGO_HOME: /drone/src/.cargo - depends_on: - - cargo-format - -- name: cargo-test - image: prima/bridge.rs-ci:${DRONE_COMMIT} - commands: - - cargo make --profile drone test - environment: - BUILD_ENV: dev - CARGO_HOME: /drone/src/.cargo - CARGO_HTTP_CAINFO: "" - depends_on: - - cargo-clippy-ci - -- name: cargo-build - image: prima/bridge.rs-ci:${DRONE_COMMIT} - commands: - - cargo make --profile drone build-ci - environment: - BUILD_ENV: dev - CARGO_HOME: /drone/src/.cargo - when: - branch: - exclude: - - master - depends_on: - - cargo-test - -- name: cache-cleanup - image: prima/bridge.rs-ci:${DRONE_COMMIT} - commands: - - cargo make --profile drone cache-cleanup - when: - branch: - - master - depends_on: - - cargo-build - - cargo-format - - cargo-clippy-ci - - cargo-test - -- name: cache-save - image: public.ecr.aws/prima/drone-tools:1.21.3 - commands: - - . /etc/profile.d/ecs-credentials-endpoint - - cache-save target - environment: - BUCKET_NAME: prima-ci-cache - volumes: - - name: ecs - path: /etc/profile.d/ecs-credentials-endpoint - - name: docker - path: /var/run/docker.sock - when: - branch: - - master - depends_on: - - cache-cleanup - -volumes: -- name: docker - host: - path: /var/run/docker.sock -- name: ecs - host: - path: /etc/profile.d/ecs-credentials-endpoint - -trigger: - event: - - push - ---- -kind: pipeline -name: build-production - -platform: - os: linux - arch: amd64 - -clone: - disable: true - -steps: -- name: git-clone - image: public.ecr.aws/prima/drone-git:1.3-3 - environment: - PLUGIN_DEPTH: 5 - -- name: cache-restore - image: public.ecr.aws/prima/drone-tools:1.21.3 - commands: - - . /etc/profile.d/ecs-credentials-endpoint - - cache-restore - environment: - BUCKET_NAME: prima-ci-cache - volumes: - - name: ecs - path: /etc/profile.d/ecs-credentials-endpoint - - name: docker - path: /var/run/docker.sock - depends_on: - - git-clone - -- name: build-image - image: public.ecr.aws/prima/drone-tools:1.21.3 - commands: - - sed -i 's/USER app/USER root/g' ./Dockerfile - - docker build -t prima/bridge.rs-ci:${DRONE_COMMIT} ./ - volumes: - - name: docker - path: /var/run/docker.sock - depends_on: - - cache-restore - -- name: build-production - image: prima/bridge.rs-ci:${DRONE_COMMIT} - commands: - - . /etc/profile.d/ecs-credentials-endpoint - - ./deploy/build production - environment: - CARGO_AUTH_KEY: - from_secret: cargo_auth_key - volumes: - - name: ecs - path: /etc/profile.d/ecs-credentials-endpoint - depends_on: - - build-image - -volumes: -- name: docker - host: - path: /var/run/docker.sock -- name: ecs - host: - path: /etc/profile.d/ecs-credentials-endpoint - -trigger: - event: - - tag - ref: - - refs/tags/*.*.* - ---- -kind: pipeline -name: email-failure - -platform: - os: linux - arch: amd64 - -clone: - disable: true - -steps: -- name: email-failure - image: public.ecr.aws/prima/drone-email - settings: - from: drone@prima.it - host: email-smtp.eu-west-1.amazonaws.com - environment: - PLUGIN_PASSWORD: - from_secret: email_password - PLUGIN_USERNAME: - from_secret: email_username - -trigger: - status: - - failure - target: - exclude: - - qa-stack - - qa-it - - qa - -depends_on: -- default -- build-production - ---- -kind: signature -hmac: cec8a64e430b6ea8917086556797fb01c5189aaebc03f9d0a049768685ed6df8 - -... diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..e267736 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +# see https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners +* @primait/shared-services diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 0000000..67897a9 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,29 @@ +name: CD + +on: + release: + types: [published] + +env: + CARGO_TERM_COLOR: always + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: taiki-e/install-action@cargo-release + - uses: taiki-e/install-action@cargo-make + - name: Get version + run: | + VERSION=$(grep -m1 '^version' Cargo.toml | cut -d'"' -f2) + echo "VERSION=$VERSION" >> $GITHUB_ENV + - name: Check version + if: ${{ github.event.release.tag_name != env.VERSION }} + run: | + echo "Github ref tag [${{ github.event.release.tag_name }}] is different from Cargo.toml version [${{ env.VERSION }}]" + exit 1 + - run: cargo login "$CARGO_AUTH_KEY" + env: + CARGO_AUTH_KEY: ${{ secrets.CARGO_AUTH_KEY }} + - run: cargo make release diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a511a3f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,37 @@ +name: CI + +on: [push, pull_request] + +env: + CARGO_TERM_COLOR: always + +jobs: + lint: + # Avoid duplicate jobs on PR from a branch on the same repo + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: Swatinem/rust-cache@v2 + - uses: taiki-e/install-action@cargo-make + - run: cargo make fmt-check + - run: cargo make clippy + - run: cargo make docs + test: + # Avoid duplicate jobs on PR from a branch on the same repo + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: Swatinem/rust-cache@v2 + - uses: taiki-e/install-action@cargo-make + - run: cargo make test + + alls-green: + if: always() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name) + runs-on: ubuntu-latest + needs: + - lint + - test + steps: + - run: ${{ !contains(needs.*.result, 'failure') }} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 7c1d1ee..dcb24a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,7 +44,6 @@ reqwest-middleware = "0.2.3" http = "0.2.9" [dev-dependencies] -env_logger = "0" flate2 = "1.0" mockito = "1.0" tokio = {version = "1.16", features = ["macros", "rt-multi-thread"]} diff --git a/Makefile.toml b/Makefile.toml index 223b9b9..b13b83c 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -12,6 +12,11 @@ args = [ "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )", ] +[tasks.fmt-check] +description = "Runs the cargo rustfmt plugin." +command = "cargo" +args = ["fmt", "--", "--check"] + [tasks.test] dependencies = ["test-base", "test-auth0"] @@ -29,89 +34,13 @@ dependencies = ["build"] command = "cargo" args = ["clippy", "--all-features", "--all-targets", "--", "-D", "warnings"] -### with cargo-limit installed -[tasks.lbuild] -description = "Runs the rust compiler." -category = "Build" -install_crate = false -command = "cargo" -args = [ - "lbuild", - "@@remove-empty(CARGO_MAKE_CARGO_VERBOSE_FLAGS)", - "@@split(CARGO_MAKE_CARGO_BUILD_TEST_FLAGS, )", -] - -[tasks.ltest] -dependencies = ["ltest-async"] - -[tasks.ltest-async] -command = "cargo" -args = ["ltest"] -dependencies = ["lbuild"] - -[tasks.clean] -command = "cargo" -args = ["clean"] - -[tasks.format-ci] -description = "Runs the cargo rustfmt plugin during CI." -command = "cargo" -args = ["fmt", "--all", "--", "--check"] - -[tasks.clippy-ci] -command = "cargo" -args = ["clippy", "--all-features", "--all-targets", "--", "-D", "warnings"] - -[tasks.build-ci] -description = "Build inside CI." -command = "cargo" -args = ["build", "-j", "2", "--all-features"] - -[tasks.cache-cleanup] -description = "Clean CI cache" -dependencies = ["cargo-prune", "sweep", "delete-artifacts"] - -[tasks.sweep] -description = "Clean cargo cache with sweep" -command = "cargo sweep -t 10" -ignore_errors = true - -[tasks.cargo-prune] -description = "Run cargo prune" -command = "cargo" -args = ["prune"] - -[tasks.delete-artifacts] -description = "Remove non cachable artifacts" -script = [ - ''' - #!/bin/bash - set -e - set -x - find ./target/debug -type f -maxdepth 1 -delete || true - rm -rfv ./target/{debug,release}/deps/{*prima_bridge*} - rm -rfv ./target/{debug,release}/.fingerprint/*prima_bridge* - ''' -] - -[tasks.sweep-start] -description = "Start cargo sweep" -command = "cargo" -args = ["sweep", "-s"] - -[tasks.sweep-end] -description = "Run cargo sweep cleanup" +[tasks.docs] +description = "Build docs as they are rendered on docs.rs" command = "cargo" -args = ["sweep", "-f"] +args = ["doc", "--document-private-items", "--all-features", "--no-deps"] +env = { "RUSTDOCFLAGS" = "-Dwarnings" } -[tasks.print-stats] -description = "Print cache size" -command = "du" -args = ["-sh", "target", ".cargo"] - -[tasks.docsrs] -description = "Build docs as they are rendered on docs.rs" -env = { RUSTDOCFLAGS = "--cfg docsrs" } +[tasks.release] +description = "Task to release the package to crates.io" command = "cargo" -toolchain = "nightly" -args = ["doc", "--all-features"] +args = ["release", "publish", "--no-confirm", "--allow-branch \"*\"", "--all-features", "--execute"] \ No newline at end of file diff --git a/deploy/build b/deploy/build deleted file mode 100755 index c629629..0000000 --- a/deploy/build +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash - -############################################################################# -# # -# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN # -# # -############################################################################# - -# script exit when a command fails -set -o errexit -# catch a command error in pipe execution -set -o pipefail -# exit when try to use undeclared variables -# set -o nounset -# print and expand each command to stdout before executing it -set -o xtrace - -if [ $# -eq 0 ]; then - echo "Missing required argument: environment" - exit 1 -fi - -export ENV=$1 -export AWS_DEFAULT_REGION="eu-west-1" -export VERSION="${DRONE_TAG:-$DRONE_COMMIT_SHA}" - -version=$(grep -m1 '^version' Cargo.toml | cut -d'"' -f2) - -if [[ "$DRONE_TAG" != "$version" ]]; then - echo "Package version $version does not match release version $DRONE_TAG" - exit 1 -fi - -git checkout . -cargo login "$CARGO_AUTH_KEY" -cargo publish diff --git a/src/lib.rs b/src/lib.rs index 41252c2..1effb38 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,11 +44,11 @@ mod response; #[cfg_attr(docsrs, doc(cfg(feature = "auth0")))] pub mod auth0; -/// The basic Bridge type, using a [reqwest::Client](reqwest::Client) as the client. +/// The basic Bridge type, using a [reqwest::Client] as the client. pub type Bridge = BridgeImpl; -/// A Bridge instance that's generic across the client. If the [bridge builder](crate::builder::BridgeBuilder) is used -/// to construct a bridge with middleware, this type will be used to wrap the [reqwest_middleware::ClientWithMiddleware](reqwest_middleware::ClientWithMiddleware). +/// A Bridge instance that's generic across the client. If the [BridgeBuilder] is used +/// to construct a bridge with middleware, this type will be used to wrap the [reqwest_middleware::ClientWithMiddleware]. #[derive(Debug)] pub struct BridgeImpl { inner_client: T, diff --git a/src/request/request_type/graphql.rs b/src/request/request_type/graphql.rs index a4b7430..ca0e4a5 100644 --- a/src/request/request_type/graphql.rs +++ b/src/request/request_type/graphql.rs @@ -17,7 +17,7 @@ use crate::{BridgeClient, BridgeImpl, MultipartFile}; const VARIABLES: &str = "variables"; const ZERO: &str = "0"; -/// The GraphQLRequest is a struct that represent a GraphQL request to be done with a [Bridge]. +/// The GraphQLRequest is a struct that represent a GraphQL request to be done with a [crate::Bridge]. #[allow(clippy::upper_case_acronyms)] pub struct GraphQLRequest<'a, Client: BridgeClient> { id: Uuid, diff --git a/src/request/request_type/rest.rs b/src/request/request_type/rest.rs index 943b4cb..675ab39 100644 --- a/src/request/request_type/rest.rs +++ b/src/request/request_type/rest.rs @@ -15,7 +15,7 @@ use crate::errors::PrimaBridgeResult; use crate::request::{Body, DeliverableRequest, DeliverableRequestBody, MultipartFormFileField, RequestType}; use crate::{BridgeClient, BridgeImpl, MultipartFile}; -/// The RestRequest is a struct that represent a REST request to be done with a [Bridge]. +/// The RestRequest is a struct that represent a REST request to be done with a [crate::Bridge]. #[derive(Debug)] pub struct RestRequest<'a, Client: BridgeClient> { id: Uuid, diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 28a0c4d..ed519f4 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -6,7 +6,6 @@ use reqwest::Url; #[allow(unused)] pub fn enable_mockito_logging() { std::env::set_var("RUST_LOG", "mockito=debug"); - env_logger::init(); } #[async_trait]