name: joystream-node-docker on: push env: REPOSITORY: joystream/node KEY_NAME: joystream-github-action-key jobs: push-amd64: name: Build joystream/node Docker image for amd64 runs-on: ubuntu-latest outputs: tag_shasum: ${{ steps.compute_shasum.outputs.shasum }} image_exists: ${{ steps.compute_main_image_exists.outputs.image_exists }} steps: - name: Checkout uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: node-version: '14.x' - id: compute_shasum name: Compute runtime code shasum run: | export RUNTIME_CODE_SHASUM=`scripts/runtime-code-shasum.sh` echo "::set-output name=shasum::${RUNTIME_CODE_SHASUM}" - name: Login to DockerHub uses: docker/login-action@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - name: Check if we have already have the manifest on Dockerhub id: compute_main_image_exists # Will output 0 if image exists and 1 if does not exists run: | export IMAGE_EXISTS=$(docker manifest inspect ${{ env.REPOSITORY }}:${{ steps.compute_shasum.outputs.shasum }} > /dev/null ; echo $?) echo "::set-output name=image_exists::${IMAGE_EXISTS}" - name: Check if we have pre-built image on Dockerhub id: compute_image_exists # Will output 0 if image exists and 1 if does not exists run: | export IMAGE_EXISTS=$(docker manifest inspect ${{ env.REPOSITORY }}:${{ steps.compute_shasum.outputs.shasum }}-amd64 > /dev/null ; echo $?) echo "::set-output name=image_exists::${IMAGE_EXISTS}" - name: Build and push uses: docker/build-push-action@v2 with: context: . file: joystream-node.Dockerfile platforms: linux/amd64 push: true tags: ${{ env.REPOSITORY }}:${{ steps.compute_shasum.outputs.shasum }}-amd64 if: ${{ steps.compute_image_exists.outputs.image_exists == 1 }} push-arm: name: Build joystream/node Docker image for arm runs-on: ubuntu-latest strategy: matrix: platform: ['linux/arm64', 'linux/arm/v7'] include: - platform: 'linux/arm64' platform_tag: 'arm64' file: 'joystream-node.Dockerfile' - platform: 'linux/arm/v7' platform_tag: 'arm' file: 'joystream-node-armv7.Dockerfile' env: STACK_NAME: build-joystream-node-docker-ga-${{ github.run_number }}-${{ matrix.platform_tag }} steps: - name: Extract branch name shell: bash run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" id: extract_branch - name: Checkout uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: node-version: '14.x' - name: Install Ansible dependencies run: pipx inject ansible-core boto3 botocore - id: compute_shasum name: Compute runtime code shasum run: | export RUNTIME_CODE_SHASUM=`scripts/runtime-code-shasum.sh` echo "::set-output name=shasum::${RUNTIME_CODE_SHASUM}" - name: Login to DockerHub uses: docker/login-action@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - name: Check if we have pre-built image on Dockerhub id: compute_image_exists # Will output 0 if image exists and 1 if does not exists run: | export IMAGE_EXISTS=$(docker manifest inspect ${{ env.REPOSITORY }}:${{ steps.compute_shasum.outputs.shasum }}-${{ matrix.platform_tag }} > /dev/null ; echo $?) echo "::set-output name=image_exists::${IMAGE_EXISTS}" - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: us-east-1 if: ${{ steps.compute_image_exists.outputs.image_exists == 1 }} - name: Deploy to AWS CloudFormation uses: aws-actions/aws-cloudformation-github-deploy@v1 id: deploy_stack with: name: ${{ env.STACK_NAME }} template: devops/aws/cloudformation/single-instance-docker.yml no-fail-on-empty-changeset: '1' parameter-overrides: 'KeyName=${{ env.KEY_NAME }},EC2AMI=ami-00d1ab6b335f217cf,EC2InstanceType=t4g.xlarge' if: ${{ steps.compute_image_exists.outputs.image_exists == 1 }} - name: Run playbook uses: dawidd6/action-ansible-playbook@v2 with: playbook: build-arm64-playbook.yml directory: devops/aws requirements: requirements.yml key: ${{ secrets.SSH_PRIVATE_KEY }} inventory: | [all] ${{ steps.deploy_stack.outputs.PublicIp }} options: | --extra-vars "git_repo=https://github.com/${{ github.repository }} \ branch_name=${{ steps.extract_branch.outputs.branch }} \ docker_username=${{ secrets.DOCKERHUB_USERNAME }} \ docker_password=${{ secrets.DOCKERHUB_PASSWORD }} \ tag_name=${{ steps.compute_shasum.outputs.shasum }}-${{ matrix.platform_tag }} \ repository=${{ env.REPOSITORY }} dockerfile=${{ matrix.file }} \ platform=${{ matrix.platform }}" if: ${{ steps.compute_image_exists.outputs.image_exists == 1 }} - name: Delete CloudFormation Stack if: always() continue-on-error: true run: | echo "Deleting ${{ env.STACK_NAME }} stack" aws cloudformation delete-stack --stack-name ${{ env.STACK_NAME }} echo "Waiting for ${{ env.STACK_NAME }} to be deleted..." aws cloudformation wait stack-delete-complete --stack-name ${{ env.STACK_NAME }} push-manifest: name: Create manifest using both the arch images needs: [push-amd64, push-arm] # Only run this job if the image does not exist with tag equal to the shasum if: needs.push-amd64.outputs.image_exists == 1 runs-on: ubuntu-latest env: TAG_SHASUM: ${{ needs.push-amd64.outputs.tag_shasum }} steps: - name: Login to DockerHub uses: docker/login-action@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - name: Create manifest for multi-arch images run: | # get artifacts from previous steps IMAGE=${{ env.REPOSITORY }}:${{ env.TAG_SHASUM }} echo $IMAGE docker pull $IMAGE-amd64 docker pull $IMAGE-arm64 docker pull $IMAGE-arm docker manifest create $IMAGE $IMAGE-amd64 $IMAGE-arm64 $IMAGE-arm docker manifest annotate $IMAGE $IMAGE-amd64 --arch amd64 docker manifest annotate $IMAGE $IMAGE-arm64 --arch arm64 docker manifest annotate $IMAGE $IMAGE-arm --arch arm docker manifest push $IMAGE - name: Create manifest with latest tag for master if: github.ref == 'refs/heads/master' run: | IMAGE=${{ env.REPOSITORY }}:${{ env.TAG_SHASUM }} LATEST_TAG=${{ env.REPOSITORY }}:latest docker manifest create $LATEST_TAG $IMAGE-amd64 $IMAGE-arm64 $IMAGE-arm docker manifest annotate $LATEST_TAG $IMAGE-amd64 --arch amd64 docker manifest annotate $LATEST_TAG $IMAGE-arm64 --arch arm64 docker manifest annotate $LATEST_TAG $IMAGE-arm --arch arm docker manifest push $LATEST_TAG