diff --git a/.github/workflows/_build.yaml b/.github/workflows/_build.yaml new file mode 100644 index 000000000..91e85424b --- /dev/null +++ b/.github/workflows/_build.yaml @@ -0,0 +1,56 @@ +name: build image + +on: + workflow_call: + inputs: + image-tags: + type: string + required: true + description: "comma separated container image tags" + role-to-assume: + description: "role arn to be assumed" + default: 'arn:aws:iam::887442827229:role/GithubActions_decidim-cfj-cdk-deploy' + type: string + required: false + deploy-env: + type: string + required: false + description: "target environment" + default: staging + +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@v3 + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-region: "ap-northeast-1" + role-duration-seconds: 1200 + role-to-assume: "${{ inputs.role-to-assume }}" + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v1 + + - name: Docker Build + uses: docker/build-push-action@v3 + with: + push: true + builder: ${{ steps.buildx.outputs.name }} + tags: ${{ steps.login-ecr.outputs.registry }}/${{ secrets.AWS_ECR_REPO_NAME }}:${{ inputs.deploy-env }}-${{ inputs.image-tags }} + file: ./Dockerfile + context: ./ + cache-from: type=gha + cache-to: type=gha,mode=max + + + diff --git a/.github/workflows/_check.yaml b/.github/workflows/_check.yaml new file mode 100644 index 000000000..ce8859ac6 --- /dev/null +++ b/.github/workflows/_check.yaml @@ -0,0 +1,119 @@ +name: Check + +on: + workflow_call: + inputs: + ruby-version: + type: string + required: false + default: 3.0.6 + +jobs: + rubocop: + name: Rubocop + permissions: + actions: write + contents: read + id-token: write + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@v3 + + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ inputs.ruby-version }} + bundler-cache: true + + - name: Lint by RuboCop + run: | + bundle exec rubocop --parallel + + unittest: + name: Unit Test + runs-on: ubuntu-latest + env: + DATABASE_HOST: 127.0.0.1 + DATABASE_PORT: 5432 + DATABASE_USERNAME: postgres + DATABASE_PASSWORD: postgres + RAILS_ENV: test + IMAGEMAGICK_SRC: 7.1.0-50.tar.gz + SLACK_API_TOKEN: xoxb-dummy + SLACK_MESSAGE_CHANNEL: '#test' + services: + db: + image: postgres:12.14 + ports: + - 5432:5432 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + redis: + image: redis + ports: + - 6379/tcp + steps: + - name: Checkout Repo + uses: actions/checkout@v3 + + - name: apt-get + run: | + sudo apt-get update -y + sudo apt-get -yqq install libpq-dev postgresql-client libfuse2 + + - name: check imagemagick + run: | + export PATH=${GITHUB_WORKSPACE}/vendor/imagemagick7/bin:${PATH} + which convert + convert -version + + - name: Set up Ruby 3.0.6 + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.0.6 + bundler-cache: true + + - name: setup Node + uses: actions/setup-node@v3 + with: + node-version: 16.13.0 + cache: 'yarn' + + - name: install yarn + run: | + npm i -g yarn@1.22.15 + yarn install --frozen-lockfile + + - name: create assets precompile cache key + run: | + # use newest commit hash of precompile target files + git rev-parse $(git log --oneline -n 1 app/packs lib/assets Gemfile.lock yarn.lock | awk '{print $1}') > ASSETS_VERSION + + - name: asset cache + uses: actions/cache@v3 + with: + path: | + public/packs + public/assets + tmp/cache/assets + public/packs-test + key: asset-precompile-cache-${{ hashFiles('ASSETS_VERSION') }} + restore-keys: | + asset-precompile-cache-${{ hashFiles('ASSETS_VERSION') }} + asset-precompile-cache- + + - name: Migrate DB + run: | + bundle exec rails db:create db:migrate + + - name: Precompile assets + run: bundle exec rails assets:precompile + - name: Test with RSpec + run: | + bundle exec rails spec diff --git a/.github/workflows/_deploy.yaml b/.github/workflows/_deploy.yaml new file mode 100644 index 000000000..1319a4ecb --- /dev/null +++ b/.github/workflows/_deploy.yaml @@ -0,0 +1,95 @@ +name: Deploy to ecs + +on: + workflow_call: + inputs: + role-to-assume: + type: string + required: false + default: arn:aws:iam::887442827229:role/GithubActions_decidim-cfj-cdk-deploy + image-tag: + type: string + required: true + deploy-env: + type: string + required: false + description: "target environment" + default: staging + +permissions: + actions: write + contents: read + id-token: write + +jobs: + deploy: + name: aws cdk + runs-on: ubuntu-latest + timeout-minutes: 1800 + steps: + - uses: actions/checkout@v3 + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + role-to-assume: ${{ inputs.role-to-assume }} + aws-region: ap-northeast-1 + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v1 + + - name: Check if ECR Image exists with tag + if: contains(github.ref, 'tags/v') + env: + IMAGE_TAG: ${{ inputs.image-tag }} + ECR_REPOSITORY: ${{ secrets.AWS_ECR_REPO_NAME }} + run: | + EXIT_CODE=0 + aws ecr describe-images --repository-name=$ECR_REPOSITORY --image-ids=imageTag=$IMAGE_TAG 2> /dev/null || EXIT_CODE=$? + + if [[ $EXIT_CODE != 0 ]]; then + echo "${IMAGE_TAG} image tag not found" + exit 1 + fi + + - name: Checkout decidim-cfj cdk + uses: actions/checkout@v3 + with: + repository: codeforjapan/decidim-cfj-cdk + path: decidim-cfj-cdk + + - name: Setup Node + uses: actions/setup-node@v1 + with: + node-version: '18' + + - name: Cache node modules + id: cache-npm + uses: actions/cache@v3 + env: + cache-name: cache-node-modules + with: + # npm cache files are stored in `~/.npm` on Linux/macOS + path: ~/.npm + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + + - name: Install dependencies + run: npm install + working-directory: decidim-cfj-cdk + + - name: Install dependencies + run: npm install -g aws-cdk + working-directory: decidim-cfj-cdk + + - name: cdk deploy + run: cdk -c stage=$DEPLOY_ENV -c tag=$IMAGE_TAG deploy --all --require-approval never + working-directory: decidim-cfj-cdk + env: + AWS_DEFAULT_REGION: 'ap-northeast-1' + DEPLOY_ENV: ${{ inputs.deploy-env }} + IMAGE_TAG: ${{ inputs.deploy-env }}-${{ inputs.image-tag }} diff --git a/.github/workflows/_release.yaml b/.github/workflows/_release.yaml new file mode 100644 index 000000000..d5122de3a --- /dev/null +++ b/.github/workflows/_release.yaml @@ -0,0 +1,35 @@ +name: Release + +permissions: write-all + +on: + workflow_call: + outputs: + tag_name: + description: image tag name + value: ${{ jobs.release.outputs.tag_name }} + created: + description: whether release is created or not + value: ${{ jobs.release.outputs.created }} + +jobs: + release: + name: Release Please + runs-on: ubuntu-latest + outputs: + created: ${{ steps.release.outputs.release_created }} + tag_name: ${{ env.IMAGE_TAG }} + steps: + - uses: google-github-actions/release-please-action@v3 + id: release + with: + release-type: ruby + - name: Export Released Version for Image Tag + if: ${{ steps.release.outputs.release_created }} + run: | + echo "IMAGE_TAG=${{ steps.release.outputs.tag_name }}" >> $GITHUB_ENV + - name: Export Commit SHA for Image Tag + if: ${{ !steps.release.outputs.release_created }} + run: | + sha=$(echo "${{ github.sha }}" | cut -c1-7) + echo "IMAGE_TAG=$sha" >> $GITHUB_ENV diff --git a/.github/workflows/branch.yaml b/.github/workflows/branch.yaml new file mode 100644 index 000000000..5bf79b318 --- /dev/null +++ b/.github/workflows/branch.yaml @@ -0,0 +1,12 @@ +name: Pull request Check & test + +permissions: write-all + +on: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + check: + name: Check + uses: ./.github/workflows/_check.yaml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index 184b80cd9..000000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,176 +0,0 @@ -name: Deploy to ecs - -on: - push: - branches: - - develop - - master - tags: - - 'v*' - -env: - AWS_ROLE_ARN: arn:aws:iam::887442827229:role/GithubActions_decidim-cfj-cdk-deploy - -jobs: - create-app-env: - runs-on: ubuntu-latest - timeout-minutes: 60 - permissions: - actions: write - contents: read - id-token: write - outputs: - image-tag: ${{ steps.output-app-env.outputs.image-tag }} - eb-environment-name: ${{ steps.output-app-env.outputs.eb-environment-name }} - - steps: - - uses: actions/checkout@v3 - - - name: Set env to staging - id: set-env-staging - if: endsWith(github.ref, 'heads/develop') - run: | - echo "IMAGE_TAG_PREFIX=staging" >> $GITHUB_ENV - echo "EB_ENVIRONMENT_NAME=staging" >> $GITHUB_ENV - - - name: Set env to production - id: set-env-production - if: endsWith(github.ref, 'heads/master') || contains(github.ref, 'tags/v') - run: | - echo "IMAGE_TAG_PREFIX=prd-v0274" >> $GITHUB_ENV - echo "EB_ENVIRONMENT_NAME=prd-v0274" >> $GITHUB_ENV - - - name: Output App Env - id: output-app-env - run: | - echo "image-tag=${IMAGE_TAG_PREFIX}-${GITHUB_SHA::8}" >> $GITHUB_OUTPUT - echo "eb-environment-name=${EB_ENVIRONMENT_NAME}" >> $GITHUB_OUTPUT - - build: - runs-on: ubuntu-latest - timeout-minutes: 1200 - needs: create-app-env - permissions: - actions: write - contents: read - id-token: write - - steps: - - uses: actions/checkout@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - - name: Cache Docker layers - uses: actions/cache@v2 - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx- - - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v1-node16 - with: - role-to-assume: ${{ env.AWS_ROLE_ARN }} - aws-region: ap-northeast-1 - - - name: Login to Amazon ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@v1 - - - name: Build, tag, and push image to Amazon ECR - uses: docker/build-push-action@v2 - if: endsWith(github.ref, 'heads/master') || endsWith(github.ref, 'heads/develop') - id: build-image - with: - push: true - tags: ${{ steps.login-ecr.outputs.registry }}/${{ secrets.AWS_ECR_REPO_NAME }}:${{ needs.create-app-env.outputs.image-tag }} - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max - - - name: Move cache - if: endsWith(github.ref, 'heads/master') || endsWith(github.ref, 'heads/develop') - run: | - rm -rf /tmp/.buildx-cache - mv /tmp/.buildx-cache-new /tmp/.buildx-cache - - deploy: - runs-on: ubuntu-latest - timeout-minutes: 1800 - if: endsWith(github.ref, 'heads/develop') || contains(github.ref, 'tags/v') - permissions: - actions: write - contents: read - id-token: write - needs: - - create-app-env - - build - - steps: - - uses: actions/checkout@v3 - - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v1-node16 - with: - role-to-assume: ${{ env.AWS_ROLE_ARN }} - aws-region: ap-northeast-1 - - - name: Login to Amazon ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@v1 - - - name: Check if ECR Image exists with tag - if: contains(github.ref, 'tags/v') - env: - IMAGE_TAG: ${{ needs.create-app-env.outputs.image-tag }} - ECR_REPOSITORY: ${{ secrets.AWS_ECR_REPO_NAME }} - run: | - EXIT_CODE=0 - aws ecr describe-images --repository-name=$ECR_REPOSITORY --image-ids=imageTag=$IMAGE_TAG 2> /dev/null || EXIT_CODE=$? - - if [[ $EXIT_CODE != 0 ]]; then - echo "${IMAGE_TAG} image tag not found" - exit 1 - fi - - - name: Checkout decidim-cfj cdk - uses: actions/checkout@v3 - with: - repository: codeforjapan/decidim-cfj-cdk - path: decidim-cfj-cdk - - - name: Setup Node - uses: actions/setup-node@v1 - with: - node-version: '16' - - - name: Cache node modules - id: cache-npm - uses: actions/cache@v3 - env: - cache-name: cache-node-modules - with: - # npm cache files are stored in `~/.npm` on Linux/macOS - path: ~/.npm - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}- - ${{ runner.os }}-build- - ${{ runner.os }}- - - - name: Install dependencies - run: npm install - working-directory: decidim-cfj-cdk - - - name: Install dependencies - run: npm install -g aws-cdk - working-directory: decidim-cfj-cdk - - - name: cdk deploy - run: cdk -c stage=$EB_ENVIRONMENT_NAME -c tag=$IMAGE_TAG deploy --all --require-approval never - working-directory: decidim-cfj-cdk - env: - AWS_DEFAULT_REGION: 'ap-northeast-1' - EB_ENVIRONMENT_NAME: ${{ needs.create-app-env.outputs.eb-environment-name }} - IMAGE_TAG: ${{ needs.create-app-env.outputs.image-tag }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 334193224..000000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Lint - -on: - push: - branches: - - master - - develop - pull_request: - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 1 - - name: apt-get - run: | - sudo apt-get update -y - sudo apt-get -yqq install libpq-dev postgresql-client - - name: Set up Ruby 3.0.6 - uses: ruby/setup-ruby@v1 - with: - ruby-version: 3.0.6 - bundler-cache: true - - name: Lint by RuboCop - run: | - bundle exec rubocop --parallel diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml new file mode 100644 index 000000000..5cc855df4 --- /dev/null +++ b/.github/workflows/main.yaml @@ -0,0 +1,73 @@ +name: Main + +permissions: write-all + +on: + push: + branches: + - main + +jobs: + check: + name: Check + uses: ./.github/workflows/_check.yaml + + release: + uses: ./.github/workflows/_release.yaml + needs: + - check + + create-deploy-env: + runs-on: ubuntu-latest + outputs: + deploy-env: ${{ steps.output-app-env.outputs.deploy-env }} + + steps: + - uses: actions/checkout@v3 + + - name: Set env to staging + id: set-env-staging + if: endsWith(github.ref, 'heads/main') + run: | + echo "DEPLOY_ENV=staging" >> $GITHUB_ENV + + - name: Set env to production + id: set-env-production + if: ${{ needs.release.outputs.created }} + run: | + echo "DEPLOY_ENV=prd-v0274" >> $GITHUB_ENV + + - name: Output App Env + id: output-deploy-env + run: | + echo "deploy_env=${DEPLOY_ENV}" >> $GITHUB_OUTPUT + + build: + needs: + - release + - create-deploy-env + uses: ./.github/workflows/_build.yaml + with: + image-tags: "${{ needs.release.outputs.tag_name }}" + deploy-env: "${{ needs.create-deploy-env.outputs.deploy-env }}" + + stg: + needs: + - release + - build + uses: ./.github/workflows/_deploy.yaml + with: + image-tag: ${{ needs.release.outputs.tag_name }} + deploy-env: ${{ needs.create-deploy-env.outputs.deploy-env }} + secrets: inherit + + prod: + if: ${{ needs.release.outputs.created }} + needs: + - release + - stg + uses: ./.github/workflows/_deploy.yaml + with: + image-tag: ${{ needs.release.outputs.tag_name }} + deploy-env: ${{ needs.create-deploy-env.outputs.deploy-env }} + secrets: inherit diff --git a/.github/workflows/rails-test.yml b/.github/workflows/rails-test.yml deleted file mode 100644 index 2c4a5ce27..000000000 --- a/.github/workflows/rails-test.yml +++ /dev/null @@ -1,98 +0,0 @@ -name: Rails Tests - -on: - push: - branches: - - master - - develop - pull_request: - -jobs: - build: - runs-on: ubuntu-latest - - env: - DATABASE_HOST: 127.0.0.1 - DATABASE_PORT: 5432 - DATABASE_USERNAME: postgres - DATABASE_PASSWORD: postgres - RAILS_ENV: test - IMAGEMAGICK_SRC: 7.1.0-50.tar.gz - SLACK_API_TOKEN: xoxb-dummy - SLACK_MESSAGE_CHANNEL: '#test' - - services: - db: - image: postgres:12 - ports: - - 5432:5432 - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - redis: - image: redis - ports: - - 6379/tcp - - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 1 - - name: apt-get - run: | - sudo apt-get update -y - sudo apt-get -yqq install libpq-dev postgresql-client libfuse2 - - - name: check imagemagick - run: | - export PATH=${GITHUB_WORKSPACE}/vendor/imagemagick7/bin:${PATH} - which convert - convert -version - - - name: Set up Ruby 3.0.6 - uses: ruby/setup-ruby@v1 - with: - ruby-version: 3.0.6 - bundler-cache: true - - - name: setup Node - uses: actions/setup-node@v3 - with: - node-version: 16.13.0 - cache: 'yarn' - - name: install yarn - run: | - npm i -g yarn@1.22.15 - yarn install --frozen-lockfile - - - name: create assets precompile cache key - run: | - # use newest commit hash of precompile target files - git rev-parse $(git log --oneline -n 1 app/packs lib/assets Gemfile.lock yarn.lock | awk '{print $1}') > ASSETS_VERSION - - - name: asset cache - uses: actions/cache@v3 - with: - path: | - public/packs - public/assets - tmp/cache/assets - public/packs-test - key: asset-precompile-cache-${{ hashFiles('ASSETS_VERSION') }} - restore-keys: | - asset-precompile-cache-${{ hashFiles('ASSETS_VERSION') }} - asset-precompile-cache- - - - name: Migrate DB - run: | - bundle exec rails db:create db:migrate - - name: Precompile assets - run: bundle exec rails assets:precompile - - name: Test with RSpec - run: | - bundle exec rails spec diff --git a/.rubocop_ruby.yml b/.rubocop_ruby.yml index c913a7676..b97ec3447 100644 --- a/.rubocop_ruby.yml +++ b/.rubocop_ruby.yml @@ -77,11 +77,6 @@ AllCops: # Otherwise we fallback to the oldest officially supported Ruby version (2.0). TargetRubyVersion: 3.0.6 - RSpec: - Patterns: - - "(?:^|/)spec/" - - "(?:^|/)test/" - # Indent private/protected/public as deep as method definitions Layout/AccessModifierIndentation: EnforcedStyle: indent