pixelfederation/swoole-bundle

View on GitHub
.circleci/config.yml

Summary

Maintainability
Test Coverage
version: 2.1
orbs:
  codecov: codecov/codecov@1.1.0
executors:
  pixelfederation-docker-client:
    docker:
      - image: pixelfederation/docker-client:20.10.17-compose
    working_directory: ~/workdir

  pixelfederation-release-version:
    docker:
      - image: docker.io/pixelfederation/release-version-script:0.3.9
    working_directory: /usr/src/app

aliases:
    # Remote Docker config
  - &docker-remote-version
    setup_remote_docker:
      # https://circleci.com/docs/2.0/building-docker-images/#docker-version
      version: 20.10.14

  - &docker-bake
    executor: pixelfederation-docker-client
    steps:
      - checkout
      - *docker-remote-version
      - run:
          name: Export required dynamic env variables
          command: |-
            TAG="$PHP_VERSION-${BUILD_TYPE:-std}-$CIRCLE_SHA1"
            echo "export TAG='$TAG'" >> $BASH_ENV

            if [ "latest" = "$SWOOLE_VERSION" ]; then
              # LATEST_SWOOLE_VERSION="$(wget -q -O /dev/stdout https://api.github.com/repos/openswoole/swoole-src/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')"
              LATEST_SWOOLE_VERSION=4.12.1
              echo "LATEST_SWOOLE_VERSION=$LATEST_SWOOLE_VERSION"
              echo "export SWOOLE_VERSION='$LATEST_SWOOLE_VERSION'" >> $BASH_ENV
            fi;

            echo "export XDEBUG_TAG='3.2.0'" >> $BASH_ENV
      - run:
          name: Print env
          command: env
      - run:
          name: Print docker info
          command: docker info
      - run:
          name: Docker pass initialization
          command: docker-use-pass
      - run:
          name: Login to Docker Hub
          command: >-
            DOCKER_REGISTRY="docker.io"
            DOCKER_USERNAME="$DOCKER_HUB_USERNAME"
            DOCKER_PASSWORD="$DOCKER_HUB_TOKEN"
            docker-registry-login
      - run:
          name: Enable Docker Buildx
          environment:
            DOCKER_BUILDX_CONTEXT_CREATE: "1"
            DOCKER_BUILDX_BUILDER_CREATE: "1"
          command: docker-use-buildx
      - run:
          name: Docker Buildx Bake all required images
          command:
            docker buildx bake --progress=plain $SERVICES

  # Filters
  - &filter-run-on-local-branches
    filters:
      branches:
        # Forked pull requests have CIRCLE_BRANCH set to pull/XXX
        ignore: /pull\/[0-9]+/

  - &filter-run-on-forked-pull-requests
    filters:
      branches:
        # Forked pull requests have CIRCLE_BRANCH set to pull/XXX
        only: /pull\/[0-9]+/

  # Job templates
  - &job-composer-code-style
    working_directory: /usr/src/app
    steps:
      - run:
          name: Run code style checks
          command: composer cs-analyse
      - run:
          name: Run static anlaysis
          command: composer static-analyse-src
      - run:
          name: Run static anlaysis
          command: composer static-analyse-tests

  - &job-composer-unit-tests
    working_directory: /usr/src/app
    steps:
      - run:
          name: Prepare dir for test results
          command: mkdir -p phpunit
      - run:
          name: Run unit tests
          command: composer unit-tests-junit
      - store_test_results:
          path: phpunit
      - store_artifacts:
          path: phpunit

  - &mysql-for-feature-tests
    image: cimg/mysql:8.0
    auth:
      username: $DOCKER_HUB_USERNAME
      password: $DOCKER_HUB_TOKEN
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: db
      MYSQL_USER: user
      MYSQL_PASSWORD: pass

  - &mysql-for-feature-tests-wait-for-init
    run:
      # Our primary container isn't MYSQL so run a sleep command until it's ready.
      name: Waiting for MySQL to be ready
      command: |
        for i in `seq 1 30`;
        do
          nc -z $DATABASE_HOST 3306 && echo Success && exit 0
          echo -n .
          sleep 1
        done
        echo Failed waiting for MySQL && exit 1

  - &job-composer-feature-tests
    working_directory: /usr/src/app
    steps:
      - *mysql-for-feature-tests-wait-for-init
      - run:
          name: Prepare dir for test results
          command: mkdir -p phpunit
      - run:
          name: Run feature tests
          command: composer feature-tests-junit
      - store_test_results:
          path: phpunit
      - store_artifacts:
          path: phpunit

jobs:
  swoole-bundle-composer-80-code-style:
    <<: *job-composer-code-style
    docker:
      - image: docker.io/pixelfederation/swoole-bundle-composer:8.0-std-$CIRCLE_SHA1

  swoole-bundle-composer-80-unit-tests:
    <<: *job-composer-unit-tests
    docker:
      - image: docker.io/pixelfederation/swoole-bundle-composer:8.0-std-$CIRCLE_SHA1

  swoole-bundle-composer-80-lowest-unit-tests:
    <<: *job-composer-unit-tests
    docker:
      - image: docker.io/pixelfederation/swoole-bundle-composer:8.0-lowest-$CIRCLE_SHA1

  swoole-bundle-composer-81-latest-unit-tests:
    <<: *job-composer-unit-tests
    docker:
      - image: docker.io/pixelfederation/swoole-bundle-composer:8.1-latest-$CIRCLE_SHA1

  swoole-bundle-composer-82-latest-unit-tests:
    <<: *job-composer-unit-tests
    docker:
      - image: docker.io/pixelfederation/swoole-bundle-composer:8.2-latest-$CIRCLE_SHA1

  swoole-bundle-composer-80-lowest-feature-tests:
    <<: *job-composer-feature-tests
    docker:
      - image: docker.io/pixelfederation/swoole-bundle-composer:8.0-lowest-$CIRCLE_SHA1
        environment:
          DATABASE_HOST: '127.0.0.1'
      - *mysql-for-feature-tests

  swoole-bundle-composer-80-feature-tests:
    <<: *job-composer-feature-tests
    docker:
      - image: docker.io/pixelfederation/swoole-bundle-composer:8.0-std-$CIRCLE_SHA1
        environment:
          DATABASE_HOST: '127.0.0.1'
      - *mysql-for-feature-tests

  swoole-bundle-composer-81-latest-feature-tests:
    <<: *job-composer-feature-tests
    docker:
      - image: docker.io/pixelfederation/swoole-bundle-composer:8.1-latest-$CIRCLE_SHA1
        environment:
          DATABASE_HOST: '127.0.0.1'
      - *mysql-for-feature-tests

  swoole-bundle-composer-82-latest-feature-tests:
    <<: *job-composer-feature-tests
    docker:
      - image: docker.io/pixelfederation/swoole-bundle-composer:8.2-latest-$CIRCLE_SHA1
        environment:
          DATABASE_HOST: '127.0.0.1'
      - *mysql-for-feature-tests

  swoole-bundle-80-code-coverage:
    executor: pixelfederation-docker-client
    environment:
      REGISTRY: docker.io
      NAMESPACE: pixelfederation
      IMAGE: swoole-bundle
      PHP_VERSION: "8.0"
      CC_TEST_REPORTER_ID: 77af0c58a2646fe49fb7df502c38a56560e074fbc8b3086f2d33032b44c885a8
      DATABASE_HOST: 127.0.0.1
    steps:
      - checkout
      - *docker-remote-version
      - run:
          name: Export required dynamic env variables
          command: |-
            TAG="$PHP_VERSION-${BUILD_TYPE:-std}-$CIRCLE_SHA1"
            echo "export TAG='$TAG'" >> $BASH_ENV
            echo $TAG
      - run:
          name: Print env
          command: env
      - run:
          name: Print docker info
          command: docker info
      - run:
          name: Login to Docker Hub
          command: >-
            DOCKER_REGISTRY="docker.io"
            DOCKER_USERNAME="$DOCKER_HUB_USERNAME"
            DOCKER_PASSWORD="$DOCKER_HUB_TOKEN"
            docker-registry-login
      - run:
          name: Pull required docker images
          command: docker-compose pull composer coverage-pcov coverage-xdebug merge-code-coverage db
      - run:
          name: Run MySql database
          command: docker-compose up -d db
      - run:
          name: Prepare CodeClimate Code Coverage reporter
          command: |-
            wget -O cc-test-reporter https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64
            chmod +x ./cc-test-reporter
            ./cc-test-reporter before-build
          when: always
      - run:
          name: Prepare coverage results volume
          command: |-
            docker-compose up -d coverage-volume-helper
            docker-compose exec coverage-volume-helper chown 1000:1000 cov
          when: always
      - run:
          name: Run unit tests with coverage (pcov)
          command: docker-compose run --rm coverage-pcov
          when: always
      - run:
          name: Run feature tests with coverage (xdebug) and retry
          command: docker-compose run --rm coverage-xdebug-feature-with-retry
          when: always
      - run:
          name: Run feature tests with coverage (pcov)
          command: docker-compose run --rm coverage-pcov feature-code-coverage
          when: always
      - run:
          name: Merge code coverage files generated across test suites
          command: docker-compose run --rm merge-code-coverage
          when: always
      - run:
          name: Extract code coverage from container volume
          command: docker cp $(docker-compose ps -q coverage-volume-helper):/usr/src/app/cov/clover.xml clover.xml
          when: always
      - run:
          name: Send Code Coverage report to CodeClimate
          command: ./cc-test-reporter after-build -t clover --exit-code 0 --prefix /usr/src/app
          when: always
      - codecov/upload:
          file: clover.xml

  releaser-dry-run:
    executor: pixelfederation-release-version
    environment:
      DEBUG: "1"
      DRY_RUN: "1"
      GH_TOKEN: "xxx"
      GH_REPOSITORY: "pixelfederation/swoole-bundle"
    steps:
      - checkout
      - run:
          name: Dry run release-version script
          command: release-version
      - run:
          name: Dry run release-version script with debug
          when: on_fail
          environment:
            DEBUG: "1"
          command: release-version

  releaser:
    executor: pixelfederation-release-version
    environment:
      DEBUG: "1"
      DRY_RUN: "0"
      GH_RELEASE_DRAFT: "false"
      GH_REPOSITORY: "pixelfederation/swoole-bundle"
    steps:
      - checkout
      - run:
          name: Run release-version script
          command: release-version

  docker-buildx-bake-80-lowest:
    <<: *docker-bake
    environment:
      PHP_VERSION: "8.0"
      PHP_API_VERSION: "20200930"
      COMPOSER_ARGS: update --prefer-lowest
      SWOOLE_VERSION: "4.12.1"
      REGISTRY: docker.io
      NAMESPACE: pixelfederation
      IMAGE: swoole-bundle
      SERVICES: composer
      BUILD_TYPE: lowest

  docker-buildx-bake-80:
    <<: *docker-bake
    environment:
      PHP_VERSION: "8.0"
      PHP_API_VERSION: "20200930"
      REGISTRY: docker.io
      NAMESPACE: pixelfederation
      IMAGE: swoole-bundle
      SERVICES: composer coverage-xdebug coverage-pcov merge-code-coverage

  docker-buildx-bake-81-latest:
    <<: *docker-bake
    environment:
      PHP_VERSION: "8.1"
      PHP_API_VERSION: "20210902"
      COMPOSER_ARGS: update
      SWOOLE_VERSION: latest
      REGISTRY: docker.io
      NAMESPACE: pixelfederation
      IMAGE: swoole-bundle
      SERVICES: composer
      BUILD_TYPE: latest

  docker-buildx-bake-82-latest:
    <<: *docker-bake
    environment:
      PHP_VERSION: "8.2"
      PHP_API_VERSION: "20220829"
      COMPOSER_ARGS: update
      SWOOLE_VERSION: latest
      REGISTRY: docker.io
      NAMESPACE: pixelfederation
      IMAGE: swoole-bundle
      SERVICES: composer
      BUILD_TYPE: latest

  check-composer-config:
    docker:
      - image: composer:2
    steps:
      - checkout
      - run:
          name: Validate composer configuration
          command: composer validate
      - run:
          name: Check if there are any out of date dependencies
          command: echo $COMPOSER_AUTH && composer outdated --locked
  shellcheck:
    docker:
      - image: koalaman/shellcheck-alpine:stable
    steps:
      - checkout
      - run:
          name: Shellcheck "tests" directory
          command: shellcheck tests/*.sh

  validate-commit-message:
    docker:
      - image: node:lts-alpine
    steps:
      - checkout
      - run:
          name: Install git
          command: apk add --no-cache git
      - run:
          name: Install commitlint
          command: npm i -g @commitlint/cli @commitlint/config-conventional
      - run:
          name: Validate commit message format
          command: commitlint --from=HEAD~20 -V

workflows:
  version: 2.1
  pull-request-checks-trusted:
    when:
      not:
        equal: [ master, << pipeline.git.branch >> ]
    jobs:
      - validate-commit-message:
          <<: *filter-run-on-local-branches
      - shellcheck:
          <<: *filter-run-on-local-branches
      - check-composer-config:
          <<: *filter-run-on-local-branches
      - releaser-dry-run:
          <<: *filter-run-on-local-branches
      - docker-buildx-bake-80:
          context: swoole-bundle-dockerhub
          requires:
            - shellcheck
            - check-composer-config
            - validate-commit-message
      - swoole-bundle-composer-80-code-style:
          requires:
            - docker-buildx-bake-80
      - swoole-bundle-composer-80-unit-tests:
          requires:
            - docker-buildx-bake-80
      - docker-buildx-bake-80-lowest:
          context: swoole-bundle-dockerhub
          requires:
            - docker-buildx-bake-80
      - swoole-bundle-composer-80-lowest-unit-tests:
          requires:
            - docker-buildx-bake-80-lowest
      - swoole-bundle-composer-80-lowest-feature-tests:
          requires:
            - docker-buildx-bake-80-lowest
      - swoole-bundle-composer-80-feature-tests:
          requires:
            - docker-buildx-bake-80
      - swoole-bundle-80-code-coverage:
          context: swoole-bundle-dockerhub
          requires:
            - docker-buildx-bake-80
      - docker-buildx-bake-81-latest:
          context: swoole-bundle-dockerhub
          requires:
            - docker-buildx-bake-80
      - swoole-bundle-composer-81-latest-unit-tests:
          requires:
            - docker-buildx-bake-81-latest
      - swoole-bundle-composer-81-latest-feature-tests:
          requires:
            - docker-buildx-bake-81-latest
      - docker-buildx-bake-82-latest:
          context: swoole-bundle-dockerhub
          requires:
            - docker-buildx-bake-80
      - swoole-bundle-composer-82-latest-unit-tests:
          requires:
            - docker-buildx-bake-82-latest
      - swoole-bundle-composer-82-latest-feature-tests:
          requires:
            - docker-buildx-bake-82-latest

  pull-request-checks-untrusted:
    when:
      not:
        equal: [ master, << pipeline.git.branch >> ]
    jobs:
      - validate-commit-message:
          <<: *filter-run-on-forked-pull-requests
      - shellcheck:
          <<: *filter-run-on-forked-pull-requests
      - check-composer-config:
          <<: *filter-run-on-forked-pull-requests
      - releaser-dry-run:
          <<: *filter-run-on-forked-pull-requests
      - approve-docker-bake:
          type: approval
          requires:
            - shellcheck
            - check-composer-config
            - validate-commit-message
      - docker-buildx-bake-80:
          context: swoole-bundle-dockerhub
          requires:
            - approve-docker-bake
      - swoole-bundle-composer-80-code-style:
          requires:
            - docker-buildx-bake-80
      - swoole-bundle-composer-80-unit-tests:
          requires:
            - docker-buildx-bake-80
      - docker-buildx-bake-80-lowest:
          context: swoole-bundle-dockerhub
          requires:
            - docker-buildx-bake-80
      - swoole-bundle-composer-80-lowest-unit-tests:
          requires:
            - docker-buildx-bake-80-lowest
      - swoole-bundle-composer-80-lowest-feature-tests:
          requires:
            - docker-buildx-bake-80-lowest
      - swoole-bundle-composer-80-feature-tests:
          requires:
            - docker-buildx-bake-80
      - swoole-bundle-80-code-coverage:
          context: swoole-bundle-dockerhub
          requires:
            - docker-buildx-bake-80
      - docker-buildx-bake-81-latest:
          context: swoole-bundle-dockerhub
          requires:
            - docker-buildx-bake-80
      - swoole-bundle-composer-81-latest-unit-tests:
          requires:
            - docker-buildx-bake-81-latest
      - swoole-bundle-composer-81-latest-feature-tests:
          requires:
            - docker-buildx-bake-81-latest
      - docker-buildx-bake-82-latest:
          context: swoole-bundle-dockerhub
          requires:
            - docker-buildx-bake-80
      - swoole-bundle-composer-82-latest-unit-tests:
          requires:
            - docker-buildx-bake-82-latest
      - swoole-bundle-composer-82-latest-feature-tests:
          requires:
            - docker-buildx-bake-82-latest

  release:
    when:
      equal: [ master, << pipeline.git.branch >> ]
    jobs:
      - shellcheck
      - check-composer-config
      - validate-commit-message
      - releaser-dry-run
      - docker-buildx-bake-80:
          context: swoole-bundle-dockerhub
          requires:
            - shellcheck
            - check-composer-config
            - validate-commit-message
      - swoole-bundle-composer-80-code-style:
          requires:
            - docker-buildx-bake-80
      - swoole-bundle-composer-80-unit-tests:
          requires:
            - docker-buildx-bake-80
      - docker-buildx-bake-80-lowest:
          context: swoole-bundle-dockerhub
          requires:
            - docker-buildx-bake-80
      - swoole-bundle-composer-80-lowest-unit-tests:
          requires:
            - docker-buildx-bake-80-lowest
      - swoole-bundle-composer-80-lowest-feature-tests:
          requires:
            - docker-buildx-bake-80-lowest
      - swoole-bundle-composer-80-feature-tests:
          requires:
            - docker-buildx-bake-80
      - swoole-bundle-80-code-coverage:
          context: swoole-bundle-dockerhub
          requires:
            - docker-buildx-bake-80
      - docker-buildx-bake-81-latest:
          context: swoole-bundle-dockerhub
          requires:
            - docker-buildx-bake-80
      - swoole-bundle-composer-81-latest-unit-tests:
          requires:
            - docker-buildx-bake-81-latest
      - swoole-bundle-composer-81-latest-feature-tests:
          requires:
            - docker-buildx-bake-81-latest
      - docker-buildx-bake-82-latest:
          context: swoole-bundle-dockerhub
          requires:
            - docker-buildx-bake-80
      - swoole-bundle-composer-82-latest-unit-tests:
          requires:
            - docker-buildx-bake-82-latest
      - swoole-bundle-composer-82-latest-feature-tests:
          requires:
            - docker-buildx-bake-82-latest
      - approve-release:
          type: approval
          requires:
            - releaser-dry-run
            - swoole-bundle-80-code-coverage
            - swoole-bundle-composer-80-lowest-feature-tests
            - swoole-bundle-composer-80-feature-tests
            - swoole-bundle-composer-80-lowest-unit-tests
            - swoole-bundle-composer-80-unit-tests
            - swoole-bundle-composer-80-code-style
            - swoole-bundle-composer-81-latest-unit-tests
            - swoole-bundle-composer-81-latest-feature-tests
            - swoole-bundle-composer-82-latest-unit-tests
            - swoole-bundle-composer-82-latest-feature-tests
      - releaser:
          context: swoole-bundle-github
          requires:
            - approve-release