name: Publish Connector Image on: workflow_dispatch: inputs: repo: description: "Repo to check out code from. Defaults to the main airbyte repo. Set this when building connectors from forked repos." required: false default: "airbytehq/airbyte" gitref: description: "The git ref to check out from the specified repository." required: false default: master connector: description: "Airbyte Connector" required: true run-tests: description: "Should run tests when publishing" required: true default: "true" comment-id: description: "The comment-id of the slash command. Used to update the comment with the status." required: false auto-bump-version: description: "after publishing, the workflow will automatically bump the connector version in definitions and generate seed spec" required: true default: "true" parallel: description: "Switching this to true will spin up 5 build agents instead of 1 and allow multi connector publishes to run in parallel" required: true default: "false" jobs: find_valid_pat: name: "Find a PAT with room for actions" timeout-minutes: 10 runs-on: ubuntu-latest outputs: pat: ${{ steps.variables.outputs.pat }} steps: - name: Checkout Airbyte uses: actions/checkout@v2 - name: Check PAT rate limits id: variables run: | ./tools/bin/find_non_rate_limited_PAT \ ${{ secrets.AIRBYTEIO_PAT }} \ ${{ secrets.OSS_BUILD_RUNNER_GITHUB_PAT }} \ ${{ secrets.SUPERTOPHER_PAT }} \ ${{ secrets.DAVINCHIA_PAT }} ## Gradle Build # In case of self-hosted EC2 errors, remove this block. start-publish-image-runner-0: name: Start Build EC2 Runner 0 runs-on: ubuntu-latest needs: find_valid_pat outputs: label: ${{ steps.start-ec2-runner.outputs.label }} ec2-instance-id: ${{ steps.start-ec2-runner.outputs.ec2-instance-id }} steps: - name: Checkout Airbyte uses: actions/checkout@v2 with: repository: ${{ github.event.inputs.repo }} ref: ${{ github.event.inputs.gitref }} - name: Start AWS Runner id: start-ec2-runner uses: ./.github/actions/start-aws-runner with: aws-access-key-id: ${{ secrets.SELF_RUNNER_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.SELF_RUNNER_AWS_SECRET_ACCESS_KEY }} github-token: ${{ needs.find_valid_pat.outputs.pat }} label: ${{ github.run_id }}-publisher start-publish-image-runner-1: if: github.event.inputs.parallel == 'true' && success() name: Start Build EC2 Runner 1 runs-on: ubuntu-latest needs: find_valid_pat outputs: label: ${{ steps.start-ec2-runner.outputs.label }} ec2-instance-id: ${{ steps.start-ec2-runner.outputs.ec2-instance-id }} steps: - name: Checkout Airbyte uses: actions/checkout@v2 with: repository: ${{ github.event.inputs.repo }} ref: ${{ github.event.inputs.gitref }} - name: Start AWS Runner id: start-ec2-runner uses: ./.github/actions/start-aws-runner with: aws-access-key-id: ${{ secrets.SELF_RUNNER_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.SELF_RUNNER_AWS_SECRET_ACCESS_KEY }} github-token: ${{ needs.find_valid_pat.outputs.pat }} label: ${{ github.run_id }}-publisher start-publish-image-runner-2: if: github.event.inputs.parallel == 'true' && success() name: Start Build EC2 Runner 2 runs-on: ubuntu-latest needs: find_valid_pat outputs: label: ${{ steps.start-ec2-runner.outputs.label }} ec2-instance-id: ${{ steps.start-ec2-runner.outputs.ec2-instance-id }} steps: - name: Checkout Airbyte uses: actions/checkout@v2 with: repository: ${{ github.event.inputs.repo }} ref: ${{ github.event.inputs.gitref }} - name: Start AWS Runner id: start-ec2-runner uses: ./.github/actions/start-aws-runner with: aws-access-key-id: ${{ secrets.SELF_RUNNER_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.SELF_RUNNER_AWS_SECRET_ACCESS_KEY }} github-token: ${{ needs.find_valid_pat.outputs.pat }} label: ${{ github.run_id }}-publisher start-publish-image-runner-3: if: github.event.inputs.parallel == 'true' && success() name: Start Build EC2 Runner 3 runs-on: ubuntu-latest needs: find_valid_pat outputs: label: ${{ steps.start-ec2-runner.outputs.label }} ec2-instance-id: ${{ steps.start-ec2-runner.outputs.ec2-instance-id }} steps: - name: Checkout Airbyte uses: actions/checkout@v2 with: repository: ${{ github.event.inputs.repo }} ref: ${{ github.event.inputs.gitref }} - name: Start AWS Runner id: start-ec2-runner uses: ./.github/actions/start-aws-runner with: aws-access-key-id: ${{ secrets.SELF_RUNNER_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.SELF_RUNNER_AWS_SECRET_ACCESS_KEY }} github-token: ${{ needs.find_valid_pat.outputs.pat }} label: ${{ github.run_id }}-publisher start-publish-image-runner-4: if: github.event.inputs.parallel == 'true' && success() name: Start Build EC2 Runner 4 runs-on: ubuntu-latest needs: find_valid_pat outputs: label: ${{ steps.start-ec2-runner.outputs.label }} ec2-instance-id: ${{ steps.start-ec2-runner.outputs.ec2-instance-id }} steps: - name: Checkout Airbyte uses: actions/checkout@v2 with: repository: ${{ github.event.inputs.repo }} ref: ${{ github.event.inputs.gitref }} - name: Start AWS Runner id: start-ec2-runner uses: ./.github/actions/start-aws-runner with: aws-access-key-id: ${{ secrets.SELF_RUNNER_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.SELF_RUNNER_AWS_SECRET_ACCESS_KEY }} github-token: ${{ needs.find_valid_pat.outputs.pat }} label: ${{ github.run_id }}-publisher preprocess-matrix: needs: start-publish-image-runner-0 runs-on: ${{ needs.start-publish-image-runner-0.outputs.label }} outputs: connectorjson: ${{ steps.preprocess.outputs.connectorjson }} steps: # given a string input of a single connector or comma separated list of connectors e.g. connector1, connector2 # this step builds an array, by removing whitespace, add in quotation marks around connectors and braces [ ] at the start and end # finally, it sets it as output from this job so we can use this array of connectors as our matrix strategy for publishing - id: preprocess run: | start="[\"" replace="\",\"" end="\"]" stripped_connector="$(echo "${{ github.event.inputs.connector }}" | tr -d ' ')" middle=${stripped_connector//,/$replace} full="$start$middle$end" echo "::set-output name=connectorjson::$full" write-initial-output-to-comment: name: Set up git comment if: github.event.inputs.comment-id needs: start-publish-image-runner-0 runs-on: ${{ needs.start-publish-image-runner-0.outputs.label }} steps: - name: Print start message if: github.event.inputs.comment-id && success() uses: peter-evans/create-or-update-comment@v1 with: comment-id: ${{ github.event.inputs.comment-id }} body: | > :clock2: Publishing the following connectors:
${{ github.event.inputs.connector }}
Running tests before publishing: **${{ github.event.inputs.run-tests }}**
https://github.com/${{github.repository}}/actions/runs/${{github.run_id}} - name: Create table header uses: peter-evans/create-or-update-comment@v1 with: comment-id: ${{ github.event.inputs.comment-id }} body: |
| Connector | Published | Definitions generated | - name: Create table separator uses: peter-evans/create-or-update-comment@v1 with: comment-id: ${{ github.event.inputs.comment-id }} body: | | --- | --- | --- | publish-image: timeout-minutes: 240 needs: - start-publish-image-runner-0 - preprocess-matrix - write-initial-output-to-comment strategy: max-parallel: 5 fail-fast: false matrix: connector: ${{ fromJSON(needs.preprocess-matrix.outputs.connectorjson) }} runs-on: runner-pool-${{ github.run_id }} environment: more-secrets steps: - name: Set up Cloud SDK uses: google-github-actions/setup-gcloud@v0 with: service_account_key: ${{ secrets.SPEC_CACHE_SERVICE_ACCOUNT_KEY }} export_default_credentials: true - name: Search for valid connector name format id: regex uses: AsasInnab/regex-action@v1 with: regex_pattern: "^(connectors|bases)/[a-zA-Z0-9-_]+$" regex_flags: "i" # required to be set for this plugin search_string: ${{ matrix.connector }} - name: Validate input workflow format if: steps.regex.outputs.first_match != matrix.connector run: echo "The connector provided has an invalid format!" && exit 1 - name: Checkout Airbyte uses: actions/checkout@v2 with: repository: ${{ github.event.inputs.repo }} ref: ${{ github.event.inputs.gitref }} token: ${{ secrets.OCTAVIA_PAT }} - name: Install Java uses: actions/setup-java@v1 with: java-version: "17" - name: Install Python uses: actions/setup-python@v2 with: python-version: "3.9" - name: Install Pyenv and Tox run: | python3 -m pip install --quiet virtualenv==16.7.9 --user rm -r venv || echo "no pre-existing venv" python3 -m virtualenv venv source venv/bin/activate pip install --quiet tox==3.24.4 - name: Install yq if: github.event.inputs.auto-bump-version == 'true' && success() run: | sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys CC86BB64 sudo add-apt-repository ppa:rmescandon/yq sudo apt update sudo apt install yq -y - name: Test and install CI scripts # all CI python packages have the prefix "ci_" run: | source venv/bin/activate tox -r -c ./tools/tox_ci.ini pip install --quiet -e ./tools/ci_* - name: Write Integration Test Credentials for ${{ matrix.connector }} run: | source venv/bin/activate ci_credentials ${{ matrix.connector }} env: GCP_GSM_CREDENTIALS: ${{ secrets.GCP_GSM_CREDENTIALS }} - name: Set Name and Version Environment Vars if: startsWith(matrix.connector, 'connectors') run: | source tools/lib/lib.sh DOCKERFILE=airbyte-integrations/${{ matrix.connector }}/Dockerfile echo "IMAGE_NAME=$(echo ${{ matrix.connector }} | cut -d"/" -f2)" >> $GITHUB_ENV echo "IMAGE_VERSION=$(_get_docker_image_version ${DOCKERFILE})" >> $GITHUB_ENV - name: Prepare Sentry if: startsWith(matrix.connector, 'connectors') run: | curl -sL https://sentry.io/get-cli/ | bash || echo "sentry cli already installed" - name: Create Sentry Release if: startsWith(matrix.connector, 'connectors') run: | sentry-cli releases set-commits "${{ env.IMAGE_NAME }}@${{ env.IMAGE_VERSION }}" --auto --ignore-missing env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_CONNECTOR_RELEASE_AUTH_TOKEN }} SENTRY_ORG: airbyte-5j SENTRY_PROJECT: airbyte-connectors - name: Publish ${{ matrix.connector }} run: | echo "$SPEC_CACHE_SERVICE_ACCOUNT_KEY" > spec_cache_key_file.json && docker login -u ${DOCKER_HUB_USERNAME} -p ${DOCKER_HUB_PASSWORD} ./tools/integrations/manage.sh publish airbyte-integrations/${{ matrix.connector }} ${{ github.event.inputs.run-tests }} --publish_spec_to_cache id: publish env: DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }} # Oracle expects this variable to be set. Although usually present, this is not set by default on Github virtual runners. TZ: UTC - name: Finalize Sentry release if: startsWith(matrix.connector, 'connectors') run: | sentry-cli releases finalize "${{ env.IMAGE_NAME }}@${{ env.IMAGE_VERSION }}" env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_CONNECTOR_RELEASE_AUTH_TOKEN }} SENTRY_ORG: airbyte-5j SENTRY_PROJECT: airbyte-connectors - name: Check if connector in definitions yaml if: github.event.inputs.auto-bump-version == 'true' && success() run: | connector="airbyte/${{ env.IMAGE_NAME }}" definitionpath=./airbyte-config/init/src/main/resources/seed/ sourcecheck=$(yq e ".. | select(has(\"dockerRepository\")) | select(.dockerRepository == \"$connector\")" "$definitionpath"source_definitions.yaml) destcheck=$(yq e ".. | select(has(\"dockerRepository\")) | select(.dockerRepository == \"$connector\")" "$definitionpath"destination_definitions.yaml) if [[ (-z "$sourcecheck" && -z "$destcheck") ]] then exit 1 fi - name: Bump version in definitions yaml if: github.event.inputs.auto-bump-version == 'true' && success() run: | connector="airbyte/${{ env.IMAGE_NAME }}" definitionpath=./airbyte-config/init/src/main/resources/seed/ sourcename=$(yq e ".[] | select(has(\"dockerRepository\")) | select(.dockerRepository == \"$connector\") | .name" "$definitionpath"source_definitions.yaml) destname=$(yq e ".[] | select(has(\"dockerRepository\")) | select(.dockerRepository == \"$connector\") | .name" "$definitionpath"destination_definitions.yaml) if [ -z "$sourcename" ] then yq e "(.[] | select(.name == \"$destname\").dockerImageTag)|=\"${{ env.IMAGE_VERSION }}\"" -i "$definitionpath"destination_definitions.yaml else yq e "(.[] | select(.name == \"$sourcename\").dockerImageTag)|=\"${{ env.IMAGE_VERSION }}\"" -i "$definitionpath"source_definitions.yaml fi - name: Run gradle process changes if: github.event.inputs.auto-bump-version == 'true' && success() run: | ./gradlew :airbyte-config:init:processResources - name: git config if: github.event.inputs.auto-bump-version == 'true' && success() run: | git config user.name 'Octavia Squidington III' git config user.email 'octavia-squidington-iii@users.noreply.github.com' - name: git commit and push if: github.event.inputs.auto-bump-version == 'true' && success() run: | git add -u git commit -m "auto-bump connector version" git pull origin ${{ github.event.inputs.gitref }} git push origin ${{ github.event.inputs.gitref }} id: auto-bump - name: Process outcomes into emojis if: ${{ always() && github.event.inputs.comment-id }} run: | if [[ ${{ steps.publish.outcome }} = "success" ]]; then echo "PUBLISH_OUTCOME=:white_check_mark:" >> $GITHUB_ENV else echo "PUBLISH_OUTCOME=:x:" >> $GITHUB_ENV fi if [[ ${{ steps.auto-bump.outcome }} = "success" ]]; then echo "AUTO_BUMP_OUTCOME=:white_check_mark:" >> $GITHUB_ENV else echo "AUTO_BUMP_OUTCOME=:x:" >> $GITHUB_ENV fi - name: Add connector outcome line to table if: ${{ always() && github.event.inputs.comment-id }} uses: peter-evans/create-or-update-comment@v1 with: comment-id: ${{ github.event.inputs.comment-id }} body: | | ${{ matrix.connector }} | ${{ env.PUBLISH_OUTCOME }} | ${{ env.AUTO_BUMP_OUTCOME }} | add-helpful-info-to-git-comment: if: ${{ always() && github.event.inputs.comment-id }} name: Add extra info to git comment needs: - start-publish-image-runner-0 # required to get output from the start-runner job - publish-image # required to wait when the main job is done runs-on: ubuntu-latest steps: - name: Add hint for manual seed definition update uses: peter-evans/create-or-update-comment@v1 with: comment-id: ${{ github.event.inputs.comment-id }} body: |
if you have connectors that successfully published but failed definition generation, follow [step 4 here ▶️](https://docs.airbyte.com/connector-development/#publishing-a-connector) # In case of self-hosted EC2 errors, remove this block. stop-publish-image-runner-0: if: ${{ always() }} # required to stop the runner even if the error happened in the previous jobs name: Stop Build EC2 Runner needs: - start-publish-image-runner-0 # required to get output from the start-runner job - preprocess-matrix - publish-image # required to wait when the main job is done - find_valid_pat - add-helpful-info-to-git-comment runs-on: ubuntu-latest steps: - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.SELF_RUNNER_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.SELF_RUNNER_AWS_SECRET_ACCESS_KEY }} aws-region: us-east-2 - name: Stop EC2 runner uses: airbytehq/ec2-github-runner@base64v1.1.0 with: mode: stop github-token: ${{ needs.find_valid_pat.outputs.pat }} label: ${{ needs.start-publish-image-runner-0.outputs.label }} ec2-instance-id: ${{ needs.start-publish-image-runner-0.outputs.ec2-instance-id }} stop-publish-image-runner-multi: if: ${{ always() && github.event.inputs.parallel == 'true' }} name: Stop Build EC2 Runner needs: - start-publish-image-runner-0 - start-publish-image-runner-1 - start-publish-image-runner-2 - start-publish-image-runner-3 - start-publish-image-runner-4 - preprocess-matrix - publish-image # required to wait when the main job is done - find_valid_pat strategy: fail-fast: false matrix: ec2-instance: [ { "label": "${{ needs.start-publish-image-runner-1.outputs.label }}", "id": "${{ needs.start-publish-image-runner-1.outputs.ec2-instance-id }}", }, { "label": "${{ needs.start-publish-image-runner-2.outputs.label }}", "id": "${{ needs.start-publish-image-runner-2.outputs.ec2-instance-id }}", }, { "label": "${{ needs.start-publish-image-runner-3.outputs.label }}", "id": "${{ needs.start-publish-image-runner-3.outputs.ec2-instance-id }}", }, { "label": "${{ needs.start-publish-image-runner-4.outputs.label }}", "id": "${{ needs.start-publish-image-runner-4.outputs.ec2-instance-id }}", }, ] runs-on: ubuntu-latest steps: - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.SELF_RUNNER_AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.SELF_RUNNER_AWS_SECRET_ACCESS_KEY }} aws-region: us-east-2 - name: Stop EC2 runner uses: airbytehq/ec2-github-runner@base64v1.1.0 with: mode: stop github-token: ${{ needs.find_valid_pat.outputs.pat }} label: ${{ matrix.ec2-instance.label }} ec2-instance-id: ${{ matrix.ec2-instance.id }}