# Copyright (c) 2020 The DAML Authors. All rights reserved. # SPDX-License-Identifier: Apache-2.0 # Azure Pipelines file, see https://aka.ms/yaml # Enable builds on all branches trigger: # Build every commit as our release process relies on # the release process being built alone. batch: false branches: include: - master # Enable PR triggers that target the master branch pr: autoCancel: true # cancel previous builds on push branches: include: - master jobs: - job: git_sha pool: name: 'linux-pool' steps: - bash: | set -euo pipefail if [ "$(Build.Reason)" == "PullRequest" ]; then echo "##vso[task.setvariable variable=branch;isOutput=true]$(git rev-parse HEAD^2)" echo "##vso[task.setvariable variable=master;isOutput=true]$(git rev-parse HEAD^1)" echo "##vso[task.setvariable variable=fork_point;isOutput=true]$(git merge-base $(git rev-parse HEAD^1) $(git rev-parse HEAD^2))" else echo "##vso[task.setvariable variable=branch;isOutput=true]$(git rev-parse HEAD)" echo "##vso[task.setvariable variable=master;isOutput=true]$(git rev-parse HEAD^1)" echo "##vso[task.setvariable variable=fork_point;isOutput=true]$(git rev-parse HEAD^1)" fi name: out - job: check_standard_change_label condition: eq(variables['Build.Reason'], 'PullRequest') pool: name: 'linux-pool' steps: - checkout: self - bash: | set -euo pipefail has_changed_infra_folder () { git diff origin/master --name-only | grep -q '^infra/' } fail_if_missing_std_change_label () { curl https://api.github.com/repos/digital-asset/daml/pulls/$PR -s | jq -r '.labels[].name' | grep -q '^Standard-Change$' } if has_changed_infra_folder; then fail_if_missing_std_change_label fi env: PR: $(System.PullRequest.PullRequestNumber) - job: check_changelog_entry condition: eq(variables['Build.Reason'], 'PullRequest') pool: name: 'linux-pool' steps: - checkout: self - bash: ci/check-changelog.sh - job: Linux dependsOn: - check_for_release variables: release_sha: $[ dependencies.check_for_release.outputs['out.release_sha'] ] release_tag: $[ coalesce(dependencies.check_for_release.outputs['out.release_tag'], '0.0.0') ] trigger_sha: $[ dependencies.check_for_release.outputs['out.trigger_sha'] ] is_release: $[ dependencies.check_for_release.outputs['out.is_release'] ] timeoutInMinutes: 360 pool: name: 'linux-pool' steps: - template: ci/report-start.yml - checkout: self - bash: | set -euo pipefail eval "$(./dev-env/bin/dade-assist)" git checkout $(release_sha) git checkout $(trigger_sha) -- docs/source/support/release-notes.rst name: checkout_release condition: eq(variables.is_release, 'true') - template: ci/build-unix.yml parameters: release_tag: $(release_tag) - bash: | set -euo pipefail eval "$(./dev-env/bin/dade-assist)" bazel build //release:release ./bazel-bin/release/release --release-dir "$(mktemp -d)" - template: ci/tell-slack-failed.yml - template: ci/report-end.yml - job: macOS dependsOn: - check_for_release timeoutInMinutes: 360 pool: vmImage: 'macOS-10.14' variables: nix-cache-key: $(Build.StagingDirectory)/macos-nix-key nix-cache-path: /tmp/nix-cache/ bazel-repo-cache-key: $(Build.StagingDirectory)/bazel-repo-cache-key bazel-repo-cache-path: $(Agent.BuildDirectory)/.bazel-cache/repo release_sha: $[ dependencies.check_for_release.outputs['out.release_sha'] ] release_tag: $[ coalesce(dependencies.check_for_release.outputs['out.release_tag'], '0.0.0') ] trigger_sha: $[ dependencies.check_for_release.outputs['out.trigger_sha'] ] is_release: $[ dependencies.check_for_release.outputs['out.is_release'] ] steps: - template: ci/report-start.yml - checkout: self - bash: | set -euo pipefail eval "$(./dev-env/bin/dade-assist)" git checkout $(release_sha) git checkout $(trigger_sha) -- docs/source/support/release-notes.rst name: checkout_release condition: eq(variables.is_release, 'true') - bash: echo $(git log -n1 --pretty=format:%H dev-env nix azure-pipelines.yml) >> $(nix-cache-key) displayName: nix cache key - task: CacheBeta@0 inputs: key: $(nix-cache-key) | v2 path: $(nix-cache-path) - bash: | set -euo pipefail if [[ -e $(nix-cache-path) ]]; then DIR=$(pwd) sudo mkdir /nix && sudo chown $USER /nix cd /nix tar xzf $(nix-cache-path)/nix.tar.gz cd $DIR curl -sfL https://nixos.org/releases/nix/nix-2.3.2/install | bash fi displayName: restore cache - bash: echo $(git log -n1 --pretty=format:%H azure-pipelines.yml $(find . -name \*.bazel -or -name \*.bzl -or -name WORKSPACE -or -name BUILD)) >> $(bazel-repo-cache-key) displayName: bazel repo cache key - task: CacheBeta@0 inputs: key: $(bazel-repo-cache-key) path: $(bazel-repo-cache-path) - template: ci/build-unix.yml parameters: release_tag: $(release_tag) - bash: | set -euo pipefail if [[ ! -e $(nix-cache-path) ]]; then mkdir -p $(nix-cache-path) cd /nix GZIP=-9 tar czf $(nix-cache-path)/nix.tar.gz store var fi displayName: create nix cache - bash: mkdir -p $(bazel-repo-cache-path) displayName: ensure bazel repo cache exists - template: ci/tell-slack-failed.yml - template: ci/report-end.yml - job: Windows dependsOn: - check_for_release variables: release_sha: $[ dependencies.check_for_release.outputs['out.release_sha'] ] release_tag: $[ coalesce(dependencies.check_for_release.outputs['out.release_tag'], '0.0.0') ] trigger_sha: $[ dependencies.check_for_release.outputs['out.trigger_sha'] ] is_release: $[ dependencies.check_for_release.outputs['out.is_release'] ] timeoutInMinutes: 360 pool: name: 'windows-pool' steps: - template: ci/report-start.yml - checkout: self - bash: | set -euo pipefail eval "$(./dev-env/bin/dade-assist)" git checkout $(release_sha) git checkout $(trigger_sha) -- docs/source/support/release-notes.rst name: checkout_release condition: eq(variables.is_release, 'true') - template: ci/build-windows.yml parameters: release_tag: $(release_tag) - template: ci/tell-slack-failed.yml - template: ci/report-end.yml - job: perf dependsOn: - check_for_release variables: release_sha: $[ dependencies.check_for_release.outputs['out.release_sha'] ] release_tag: $[ coalesce(dependencies.check_for_release.outputs['out.release_tag'], '0.0.0') ] trigger_sha: $[ dependencies.check_for_release.outputs['out.trigger_sha'] ] is_release: $[ dependencies.check_for_release.outputs['out.is_release'] ] timeoutInMinutes: 60 pool: name: 'linux-pool' steps: - template: ci/report-start.yml - checkout: self - bash: | set -euo pipefail eval "$(./dev-env/bin/dade-assist)" git checkout $(release_sha) git checkout $(trigger_sha) -- docs/source/support/release-notes.rst name: checkout_release condition: eq(variables.is_release, 'true') - bash: ci/dev-env-install.sh displayName: 'Build/Install the Developer Environment' - bash: ci/configure-bazel.sh displayName: 'Configure Bazel' env: IS_FORK: $(System.PullRequest.IsFork) # to upload to the bazel cache GOOGLE_APPLICATION_CREDENTIALS_CONTENT: $(GOOGLE_APPLICATION_CREDENTIALS_CONTENT) - bash: | set -euo pipefail eval "$(./dev-env/bin/dade-assist)" DAML_SDK_RELEASE_VERSION=$(release_tag) bazel run -- //ledger/sandbox-perf -foe true -i1 -f1 -wi 1 -bm avgt -rf csv -rff "$(Build.StagingDirectory)/sandbox-perf.csv" - task: PublishBuildArtifacts@1 condition: succeededOrFailed() inputs: pathtoPublish: '$(Build.StagingDirectory)' artifactName: 'Perf test logs' - template: ci/tell-slack-failed.yml - template: ci/report-end.yml - job: check_for_release dependsOn: - git_sha variables: branch_sha: $[ dependencies.git_sha.outputs['out.branch'] ] fork_sha: $[ dependencies.git_sha.outputs['out.fork_point'] ] pool: name: "linux-pool" steps: - bash: | set -euo pipefail ./release.sh check is_release_commit() { changed="$(git diff-tree --no-commit-id --name-only -r $(branch_sha) $(fork_sha) | sort)" stable=$(printf "LATEST\ndocs/source/support/release-notes.rst" | sort) snapshot="LATEST" [ "$snapshot" = "$changed" ] || [ "$stable" = "$changed" ] } if is_release_commit; then echo "##vso[task.setvariable variable=is_release;isOutput=true]true" echo "##vso[task.setvariable variable=trigger_sha;isOutput=true]$(branch_sha)" echo "##vso[task.setvariable variable=release_sha;isOutput=true]$(cat LATEST | awk '{print $1}')" echo "##vso[task.setvariable variable=release_tag;isOutput=true]$(cat LATEST | awk '{print $2}')" else echo "##vso[task.setvariable variable=is_release;isOutput=true]false" fi name: out - job: windows_installer dependsOn: [ "check_for_release", "Windows" ] condition: and(succeeded(), eq(dependencies.check_for_release.outputs['out.is_release'], 'true'), eq(variables['Build.SourceBranchName'], 'master')) pool: name: 'windows-pool' variables: release_sha: $[ dependencies.check_for_release.outputs['out.release_sha'] ] release_tag: $[ dependencies.check_for_release.outputs['out.release_tag'] ] steps: - template: ci/report-start.yml - bash: | set -euo pipefail eval "$(./dev-env/bin/dade-assist)" git checkout $(release_sha) - bash: ci/configure-bazel.sh env: IS_FORK: $(System.PullRequest.IsFork) - bash: | set -euo pipefail eval "$(./dev-env/bin/dade-assist)" export DAML_SDK_RELEASE_VERSION=$(release_tag) bazel build //release/windows-installer:windows-installer INSTALLER=daml-sdk-$(release_tag)-windows.exe mv "bazel-bin/release/windows-installer/daml-sdk-installer.exe" "$(Build.StagingDirectory)/$INSTALLER" chmod +x "$(Build.StagingDirectory)/$INSTALLER" cleanup () { rm -f signing_key.pfx } trap cleanup EXIT echo "$SIGNING_KEY" | base64 -d > signing_key.pfx MSYS_NO_PATHCONV=1 signtool.exe sign '/f' signing_key.pfx '/fd' sha256 '/tr' "http://timestamp.digicert.com" '/v' "$(Build.StagingDirectory)/$INSTALLER" rm signing_key.pfx echo "##vso[task.setvariable variable=installer;isOutput=true]$INSTALLER" bazel build //release:sdk-release-tarball TARBALL=daml-sdk-$(release_tag)-windows.tar.gz cp bazel-bin/release/sdk-release-tarball.tar.gz '$(Build.StagingDirectory)'/$TARBALL echo "##vso[task.setvariable variable=tarball;isOutput=true]$TARBALL" name: publish env: SIGNING_KEY: $(microsoft-code-signing) - task: PublishPipelineArtifact@0 inputs: targetPath: $(Build.StagingDirectory)/$(publish.installer) artifactName: $(publish.installer) - task: PublishPipelineArtifact@0 inputs: targetPath: $(Build.StagingDirectory)/$(publish.tarball) artifactName: $(publish.tarball) - template: ci/tell-slack-failed.yml - template: ci/report-end.yml - job: linux_tarball dependsOn: [ "check_for_release", "Linux" ] condition: and(succeeded(), eq(dependencies.check_for_release.outputs['out.is_release'], 'true'), eq(variables['Build.SourceBranchName'], 'master')) variables: release_sha: $[ dependencies.check_for_release.outputs['out.release_sha'] ] release_tag: $[ dependencies.check_for_release.outputs['out.release_tag'] ] pool: name: "linux-pool" steps: - bash: | set -euo pipefail eval "$(./dev-env/bin/dade-assist)" git checkout $(release_sha) - bash: ci/configure-bazel.sh env: IS_FORK: $(System.PullRequest.IsFork) - bash: | set -euo pipefail eval "$(./dev-env/bin/dade-assist)" export DAML_SDK_RELEASE_VERSION=$(release_tag) bazel build //release:release mkdir -p ~/.jfrog cleanup() { rm -f ~/.jfrog/jfrog-cli.conf } trap cleanup EXIT echo "$JFROG_CONFIG_CONTENT" > ~/.jfrog/jfrog-cli.conf unset JFROG_CONFIG_CONTENT ./bazel-bin/release/release --release-dir "$(mktemp -d)" --upload bazel build //release:sdk-release-tarball TARBALL=daml-sdk-$(release_tag)-linux.tar.gz cp bazel-bin/release/sdk-release-tarball.tar.gz $(Build.StagingDirectory)/$TARBALL echo "##vso[task.setvariable variable=tarball;isOutput=true]$TARBALL" env: JFROG_CONFIG_CONTENT: $(JFROG_CONFIG_CONTENT) GPG_KEY: $(gpg-code-signing) MAVEN_USERNAME: $(MAVEN_USERNAME) MAVEN_PASSWORD: $(MAVEN_PASSWORD) MAVEN_URL: $(MAVEN_URL) NPM_TOKEN: $(NPM_TOKEN) name: publish - task: PublishPipelineArtifact@0 inputs: targetPath: $(Build.StagingDirectory)/$(publish.tarball) artifactName: $(publish.tarball) - template: ci/tell-slack-failed.yml - template: ci/report-end.yml - job: macos_tarball dependsOn: [ "check_for_release", "macOS" ] condition: and(succeeded(), eq(dependencies.check_for_release.outputs['out.is_release'], 'true'), eq(variables['Build.SourceBranchName'], 'master')) variables: release_sha: $[ dependencies.check_for_release.outputs['out.release_sha'] ] release_tag: $[ dependencies.check_for_release.outputs['out.release_tag'] ] pool: vmImage: "macOS-10.14" steps: - bash: | set -euo pipefail eval "$(./dev-env/bin/dade-assist)" git checkout $(release_sha) - bash: ci/configure-bazel.sh env: IS_FORK: $(System.PullRequest.IsFork) - bash: | set -euo pipefail eval "$(./dev-env/bin/dade-assist)" export DAML_SDK_RELEASE_VERSION=$(release_tag) bazel build //release:sdk-release-tarball TARBALL=daml-sdk-$(release_tag)-macos.tar.gz cp bazel-bin/release/sdk-release-tarball.tar.gz $(Build.StagingDirectory)/$TARBALL echo "##vso[task.setvariable variable=tarball;isOutput=true]$TARBALL" name: publish - task: PublishPipelineArtifact@0 inputs: targetPath: $(Build.StagingDirectory)/$(publish.tarball) artifactName: $(publish.tarball) - template: ci/tell-slack-failed.yml - template: ci/report-end.yml - job: release dependsOn: [ "check_for_release", "linux_tarball", "macos_tarball", "windows_installer" ] condition: and(succeeded(), eq(dependencies.check_for_release.outputs['out.is_release'], 'true'), eq(variables['Build.SourceBranchName'], 'master')) pool: vmImage: "Ubuntu-16.04" variables: linux-tarball: $[ dependencies.linux_tarball.outputs['publish.tarball'] ] macos-tarball: $[ dependencies.macos_tarball.outputs['publish.tarball'] ] windows-tarball: $[ dependencies.windows_installer.outputs['publish.tarball'] ] windows-installer: $[ dependencies.windows_installer.outputs['publish.installer'] ] release_sha: $[ dependencies.check_for_release.outputs['out.release_sha'] ] release_tag: $[ dependencies.check_for_release.outputs['out.release_tag'] ] steps: - template: ci/report-start.yml - checkout: self persistCredentials: true - bash: | set -euxo pipefail if git tag v$(release_tag); then git push origin v$(release_tag) mkdir $(Build.StagingDirectory)/release else echo "##vso[task.setvariable variable=skip-github]TRUE" fi - task: DownloadPipelineArtifact@0 inputs: artifactName: $(linux-tarball) targetPath: $(Build.StagingDirectory)/release condition: not(eq(variables['skip-github'], 'TRUE')) - task: DownloadPipelineArtifact@0 inputs: artifactName: $(macos-tarball) targetPath: $(Build.StagingDirectory)/release condition: not(eq(variables['skip-github'], 'TRUE')) - task: DownloadPipelineArtifact@0 inputs: artifactName: $(windows-tarball) targetPath: $(Build.StagingDirectory)/release condition: not(eq(variables['skip-github'], 'TRUE')) - task: DownloadPipelineArtifact@0 inputs: artifactName: $(windows-installer) targetPath: $(Build.StagingDirectory)/release condition: not(eq(variables['skip-github'], 'TRUE')) - bash: | set -euo pipefail KEY_FILE=$(mktemp) GPG_DIR=$(mktemp -d) cleanup() { rm -rf $KEY_FILE $GPG_DIR } trap cleanup EXIT echo "$GPG_KEY" | base64 -d > $KEY_FILE gpg --homedir $GPG_DIR --no-tty --quiet --import $KEY_FILE cd $(Build.StagingDirectory)/release # Note: relies on our release artifacts not having spaces in their # names. Creates a ${f}.asc with the signature for each $f. for f in *; do gpg --homedir $GPG_DIR -ab $f done env: GPG_KEY: $(gpg-code-signing) - task: GitHubRelease@0 inputs: gitHubConnection: 'garyverhaegen-da' repositoryName: '$(Build.Repository.Name)' action: 'create' target: '$(Build.SourceVersion)' tagSource: 'auto' assets: $(Build.StagingDirectory)/release/* assetUploadMode: 'replace' addChangeLog: false isPrerelease: true condition: not(eq(variables['skip-github'], 'TRUE')) - template: ci/tell-slack-failed.yml - template: ci/report-end.yml - job: write_ledger_dump dependsOn: [ "check_for_release" ] pool: vmImage: "Ubuntu-16.04" condition: and(eq(dependencies.check_for_release.outputs['out.is_release'], 'true'), eq(variables['Build.SourceBranchName'], 'master')) variables: release_sha: $[ dependencies.check_for_release.outputs['out.release_sha'] ] release_tag: $[ dependencies.check_for_release.outputs['out.release_tag'] ] steps: - checkout: self - bash: | set -euo pipefail git checkout $(release_sha) export DAML_SDK_RELEASE_VERSION=$(release_tag) sudo mkdir -p /nix sudo chown $USER /nix curl -sfL https://nixos.org/releases/nix/nix-2.3.2/install | bash eval "$(dev-env/bin/dade-assist)" GCS_KEY=$(mktemp) cleanup () { rm -f $GCS_KEY } trap cleanup EXIT echo "$GOOGLE_APPLICATION_CREDENTIALS_CONTENT" > $GCS_KEY gcloud auth activate-service-account --key-file=$GCS_KEY export BOTO_CONFIG=/dev/null bazel build //ledger/api-server-damlonx/reference-v2:reference-ledger-dump gsutil cp bazel-bin/ledger/api-server-damlonx/reference-v2/reference-ledger-dump.out \ gs://daml-dumps/release/ledger/api-server-damlonx/reference-v2/reference-ledger-dump-$(release_tag) env: GOOGLE_APPLICATION_CREDENTIALS_CONTENT: $(GOOGLE_APPLICATION_CREDENTIALS_CONTENT) - template: ci/tell-slack-failed.yml - job: collect_build_data condition: always() dependsOn: - Linux - macOS - Windows - check_for_release - linux_tarball - macos_tarball - windows_installer - perf - release - check_standard_change_label - write_ledger_dump - git_sha pool: name: "linux-pool" variables: Linux.start: $[ dependencies.Linux.outputs['start.time'] ] Linux.machine: $[ dependencies.Linux.outputs['start.machine'] ] Linux.end: $[ dependencies.Linux.outputs['end.time'] ] Linux.status: $[ dependencies.Linux.result ] macOS.start: $[ dependencies.macOS.outputs['start.time'] ] macOS.machine: $[ dependencies.macOS.outputs['start.machine'] ] macOS.end: $[ dependencies.macOS.outputs['end.time'] ] macOS.status: $[ dependencies.macOS.result ] Windows.start: $[ dependencies.Windows.outputs['start.time'] ] Windows.machine: $[ dependencies.Windows.outputs['start.machine'] ] Windows.end: $[ dependencies.Windows.outputs['end.time'] ] Windows.status: $[ dependencies.Windows.result ] check_for_release.start: $[ dependencies.check_for_release.outputs['start.time'] ] check_for_release.machine: $[ dependencies.check_for_release.outputs['start.machine'] ] check_for_release.end: $[ dependencies.check_for_release.outputs['end.time'] ] check_for_release.status: $[ dependencies.check_for_release.result ] linux_tarball.start: $[ dependencies.linux_tarball.outputs['start.time'] ] linux_tarball.machine: $[ dependencies.linux_tarball.outputs['start.machine'] ] linux_tarball.end: $[ dependencies.linux_tarball.outputs['end.time'] ] linux_tarball.status: $[ dependencies.linux_tarball.result ] macos_tarball.start: $[ dependencies.macos_tarball.outputs['start.time'] ] macos_tarball.machine: $[ dependencies.macos_tarball.outputs['start.machine'] ] macos_tarball.end: $[ dependencies.macos_tarball.outputs['end.time'] ] macos_tarball.status: $[ dependencies.macos_tarball.result ] windows_installer.start: $[ dependencies.windows_installer.outputs['start.time'] ] windows_installer.machine: $[ dependencies.windows_installer.outputs['start.machine'] ] windows_installer.end: $[ dependencies.windows_installer.outputs['end.time'] ] windows_installer.status: $[ dependencies.windows_installer.result ] perf.start: $[ dependencies.perf.outputs['start.time'] ] perf.machine: $[ dependencies.perf.outputs['start.machine'] ] perf.end: $[ dependencies.perf.outputs['end.time'] ] perf.status: $[ dependencies.perf.result ] release.start: $[ dependencies.release.outputs['start.time'] ] release.machine: $[ dependencies.release.outputs['start.machine'] ] release.end: $[ dependencies.release.outputs['end.time'] ] release.status: $[ dependencies.release.result ] std_change.start: $[ dependencies.check_standard_change_label.outputs['start.time'] ] std_change.machine: $[ dependencies.check_standard_change_label.outputs['start.machine'] ] std_change.end: $[ dependencies.check_standard_change_label.outputs['end.time'] ] std_change.status: $[ dependencies.check_standard_change_label.result ] dump.start: $[ dependencies.write_ledger_dump.outputs['start.time'] ] dump.machine: $[ dependencies.write_ledger_dump.outputs['start.machine'] ] dump.end: $[ dependencies.write_ledger_dump.outputs['end.time'] ] dump.status: $[ dependencies.write_ledger_dump.result ] branch_sha: $[ dependencies.git_sha.outputs['out.branch'] ] master_sha: $[ dependencies.git_sha.outputs['out.master'] ] fork_sha: $[ dependencies.git_sha.outputs['out.fork_point'] ] # Using expression syntax so we get an empty string if not set, rather # than the raw $(VarName) string. Expression syntax works on the # variables key, but not on the env one, so we need an extra indirection. # Note: These Azure variables are only set for PR builds. pr.num: $[ variables['System.PullRequest.PullRequestNumber'] ] pr.branch: $[ variables['System.PullRequest.SourceBranch'] ] steps: # some change in Azure configuration makes this fail recently (2020-01). # Azure runs PR builds not on the PR commit, but on the GitHub-provided # commit that would be the result of merging the PR. Recently, it looks # like when it reaches the point of running this job (which has to run # after the macOS one, which sometimes takes up to an hour), if master # has changed in the meantime, Azure cannot find the commit it wants to # build anymore. Therefore, we tell it not to checkout anything, and # manually checkout the PR commit. - checkout: none - bash: | set -euo pipefail # Note: this is going to get the PR branch commit, not the # result of the merge (i.e. this is not using the same commit as the # other jobs in this build). # # We have seen errors getting this commit from GitHub, which we # suspect are transient network errors, so adding simple exponential # backoff to mitigate. BACKOFF=1 tell_gary() { curl -XPOST \ -i \ -H 'Content-Type: application/json' \ --data "{\"text\":\"<@UEHSF89AQ> for has failed to fetch its commit $(branch_sha) up to BACKOFF=$BACKOFF.\"}" \ $(Slack.team-daml-ci) } trap tell_gary EXIT while ! git fetch origin $(branch_sha); do if (( $BACKOFF > 500 )); then echo "Could not get commit $(branch_sha); something is very wrong." exit 1 else sleep $BACKOFF let "BACKOFF = $BACKOFF * 2" fi done if (( $BACKOFF > 1 )); then tell_gary fi trap - EXIT git checkout $(branch_sha) eval "$(./dev-env/bin/dade-assist)" REPORT=$(mktemp) cat >$REPORT < $REPORT_GZ GCS_KEY=$(mktemp) cleanup() { rm -rf $GCS_KEY } trap cleanup EXIT # Application credentials will not be set for forks. We give up on # tracking those for now. "Not set" in Azure world means set to the # expression Azure would otherwise substitute, i.e. the literal value # of the string in the `env:` block below. if [[ "${GOOGLE_APPLICATION_CREDENTIALS_CONTENT:1:${#GOOGLE_APPLICATION_CREDENTIALS_CONTENT}-1}" != '(GOOGLE_APPLICATION_CREDENTIALS_CONTENT)' ]]; then echo "$GOOGLE_APPLICATION_CREDENTIALS_CONTENT" > $GCS_KEY gcloud auth activate-service-account --key-file=$GCS_KEY BOTO_CONFIG=/dev/null gsutil cp $REPORT_GZ gs://daml-data/builds/$(Build.BuildId)_$(date -u +%Y%m%d_%H%M%SZ).json.gz else echo "Could not save build data: no credentials. Data was:" cat $REPORT fi # Linux, macOS, perf, check_std_change_label and Windows are always # required and should always succeed. # # windows_signing, release and write_ledger_dump only run on releases # and are skipped otherwise. if [[ "$(Linux.status)" != "Succeeded" || "$(macOS.status)" != "Succeeded" || "$(Windows.status)" != "Succeeded" || "$(perf.status)" != "Succeeded" || "$(dump.status)" == "Canceled" || "$(linux_tarball.status)" == "Canceled" || "$(macos_tarball.status)" == "Canceled" || "$(windows_installer.status)" == "Canceled" || "$(release.status)" == "Canceled" ]]; then exit 1 fi env: GOOGLE_APPLICATION_CREDENTIALS_CONTENT: $(GOOGLE_APPLICATION_CREDENTIALS_CONTENT) # Commit message is always set COMMIT_MSG: $(Build.SourceVersionMessage) # Because these variables are always set (in the variables block), # hopefully these should be set as expected (i.e. either correct # value or empty string, but not $(Azure.Variable.Name)). PR_NUM: $(pr.num) PR_BRANCH: $(pr.branch) - job: notify_user condition: eq(variables['Build.Reason'], 'PullRequest') dependsOn: - git_sha - collect_build_data pool: name: 'linux-pool' variables: pr.num: $[ variables['System.PullRequest.PullRequestNumber'] ] branch_sha: $[ dependencies.git_sha.outputs['out.branch'] ] status: $[ dependencies.collect_build_data.result ] steps: - checkout: none - bash: | set -euo pipefail # We have seen errors getting this commit from GitHub, which we # suspect are transient network errors, so adding simple exponential # backoff to mitigate. BACKOFF=1 tell_gary() { curl -XPOST \ -i \ -H 'Content-Type: application/json' \ --data "{\"text\":\"<@UEHSF89AQ> for has failed to fetch its commit $(branch_sha) up to BACKOFF=$BACKOFF.\"}" \ $(Slack.team-daml-ci) } trap tell_gary EXIT while ! git fetch origin $(branch_sha); do if (( $BACKOFF > 500 )); then echo "Could not get commit $(branch_sha); something is very wrong." exit 1 else sleep $BACKOFF let "BACKOFF = $BACKOFF * 2" fi done if (( $BACKOFF > 1 )); then tell_gary fi trap - EXIT git checkout $(branch_sha) tell_slack() { local MESSAGE=$1 local USER_ID=$2 curl -XPOST \ -i \ -H 'Content-Type: application/json' \ --data "{\"text\":\"<@${USER_ID}> for has completed with status ${MESSAGE}.\"}" \ $(Slack.team-daml-ci) } EMAIL=$(git log -n 1 --format=%ae) user_registered() { cat ci/slack_user_ids | grep $EMAIL } user_id() { echo $(cat ci/slack_user_ids | grep $EMAIL | awk '{print $2}') } if user_registered; then tell_slack "$(status)" "$(user_id)" else echo "User $(user_id) did not opt in for notifications." fi