diff --git a/.drone.yml b/.drone.yml index c025cdb77cdd3..45018bbcf0a30 100644 --- a/.drone.yml +++ b/.drone.yml @@ -516,11 +516,11 @@ image_pull_secrets: ################################################ # Generated using dronegen, do not edit by hand! # Use 'make dronegen' to update. -# Generated at dronegen/mac.go (main.newDarwinPipeline) +# Generated at dronegen/gha.go (main.ghaBuildPipeline) ################################################ kind: pipeline -type: exec +type: kubernetes name: push-build-darwin-amd64 trigger: event: @@ -536,167 +536,60 @@ trigger: - master - branch/* workspace: - path: /tmp/push-build-darwin-amd64 -platform: - os: darwin - arch: amd64 + path: /go clone: disable: true -concurrency: - limit: 1 steps: -- name: Set up exec runner storage - commands: - - set -u - - mkdir -p $WORKSPACE_DIR - - chmod -R u+rw $WORKSPACE_DIR - - rm -rf $WORKSPACE_DIR/go $WORKSPACE_DIR/.ssh - environment: - WORKSPACE_DIR: /tmp/push-build-darwin-amd64 - name: Check out code + image: docker:git + pull: if-not-exists commands: - - set -u - - mkdir -p $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - git clone https://github.com/gravitational/${DRONE_REPO_NAME}.git . - - git checkout ${DRONE_TAG:-$DRONE_COMMIT} - - mkdir -m 0700 $WORKSPACE_DIR/.ssh && echo "$GITHUB_PRIVATE_KEY" > $WORKSPACE_DIR/.ssh/id_rsa - && chmod 600 $WORKSPACE_DIR/.ssh/id_rsa - - ssh-keyscan -H github.com > $WORKSPACE_DIR/.ssh/known_hosts 2>/dev/null - - chmod 600 $WORKSPACE_DIR/.ssh/known_hosts - - GIT_SSH_COMMAND='ssh -i $WORKSPACE_DIR/.ssh/id_rsa -o UserKnownHostsFile=$WORKSPACE_DIR/.ssh/known_hosts - -F /dev/null' git submodule update --init e - - rm -rf $WORKSPACE_DIR/.ssh - - mkdir -p $WORKSPACE_DIR/go/cache + - mkdir -pv "/go/src/github.com/gravitational/teleport" + - cd "/go/src/github.com/gravitational/teleport" + - git init + - git remote add origin ${DRONE_REMOTE_URL} + - git fetch origin --tags + - git checkout -qf "${DRONE_COMMIT_SHA}" + - mkdir -m 0700 /root/.ssh && echo "$GITHUB_PRIVATE_KEY" > /root/.ssh/id_rsa && + chmod 600 /root/.ssh/id_rsa + - ssh-keyscan -H github.com > /root/.ssh/known_hosts 2>/dev/null && chmod 600 /root/.ssh/known_hosts + - git submodule update --init e + - mkdir -pv /go/cache + - rm -f /root/.ssh/id_rsa environment: GITHUB_PRIVATE_KEY: from_secret: GITHUB_PRIVATE_KEY - WORKSPACE_DIR: /tmp/push-build-darwin-amd64 -- name: Install Go Toolchain - commands: - - set -u - - mkdir -p /tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains - - curl --silent -O https://dl.google.com/go/$RUNTIME.darwin-amd64.tar.gz - - tar -C /tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains -xzf $RUNTIME.darwin-amd64.tar.gz - - rm -rf $RUNTIME.darwin-amd64.tar.gz - environment: - RUNTIME: go1.20.3 -- name: Install Rust Toolchain - commands: - - set -u - - export PATH=/Users/$(whoami)/.cargo/bin:$PATH - - mkdir -p /tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains - - export RUST_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets - print-rust-version) - - export CARGO_HOME=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains/cargo - - export RUST_HOME=$CARGO_HOME - - export RUSTUP_HOME=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains/rustup - - rustup toolchain install $RUST_VERSION - environment: - WORKSPACE_DIR: /tmp/push-build-darwin-amd64 -- name: Install Node Toolchain - commands: - - set -u - - export NODE_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets - print-node-version) - - export TOOLCHAIN_DIR=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains - - export NODE_DIR=$TOOLCHAIN_DIR/node-v$NODE_VERSION-darwin-x64 - - mkdir -p $TOOLCHAIN_DIR - - curl --silent -O https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-darwin-x64.tar.gz - - tar -C $TOOLCHAIN_DIR -xzf node-v$NODE_VERSION-darwin-x64.tar.gz - - rm -f node-v$NODE_VERSION-darwin-x64.tar.gz - - export PATH=$NODE_DIR/bin:$PATH - - corepack enable yarn - - echo Node reporting version $(node --version) - - echo Yarn reporting version $(yarn --version) - environment: - WORKSPACE_DIR: /tmp/push-build-darwin-amd64 -- name: Build Mac artifacts (binaries and Teleport Connect) - commands: - - set -u - - export HOME=/Users/$(whoami) - - export TOOLCHAIN_DIR=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains - - security unlock-keychain -p $${BUILDBOX_PASSWORD} login.keychain - - security find-identity -v - - export NODE_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets - print-node-version) - - export NODE_HOME=$TOOLCHAIN_DIR/node-v$NODE_VERSION-darwin-x64 - - export PATH=$NODE_HOME/bin:$PATH - - export RUST_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets - print-rust-version) - - export CARGO_HOME=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains/cargo - - export RUST_HOME=$CARGO_HOME - - export RUSTUP_HOME=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains/rustup - - export PATH=$CARGO_HOME/bin:/Users/build/.cargo/bin:$PATH - - rustup override set $RUST_VERSION - - export PATH=$TOOLCHAIN_DIR/go/bin:$PATH - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - build.assets/build-fido2-macos.sh build - - export PKG_CONFIG_PATH="$(build.assets/build-fido2-macos.sh pkg_config_path)" - - make clean release OS=$OS ARCH=$ARCH FIDO2=yes TOUCHID=yes PIV=yes - - export VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - print-version) - - export BUILD_NUMBER=$DRONE_BUILD_NUMBER - - security unlock-keychain -p $${BUILDBOX_PASSWORD} login.keychain - - security find-identity -v - - export CSC_NAME=0FFD3E3413AB4C599C53FBB1D8CA690915E33D83 - - export CONNECT_TSH_BIN_PATH=$WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build/tsh - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - yarn install && yarn build-term && yarn package-term -c.extraMetadata.version=$VERSION - environment: - APPLE_PASSWORD: - from_secret: APPLE_PASSWORD - APPLE_USERNAME: - from_secret: APPLE_USERNAME - ARCH: amd64 - BUILDBOX_PASSWORD: - from_secret: BUILDBOX_PASSWORD - GOCACHE: /tmp/push-build-darwin-amd64/go/cache - GOPATH: /tmp/push-build-darwin-amd64/go - OS: darwin - WORKSPACE_DIR: /tmp/push-build-darwin-amd64 -- name: Clean up toolchains (post) - commands: - - set -u - - export PATH=/Users/$(whoami)/.cargo/bin:$PATH - - export CARGO_HOME=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains/cargo - - export RUST_HOME=$CARGO_HOME - - export RUSTUP_HOME=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains/rustup - - export RUST_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets - print-rust-version) - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - rustup override unset - - rustup toolchain uninstall $RUST_VERSION - - rm -rf /tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED - environment: - WORKSPACE_DIR: /tmp/push-build-darwin-amd64 - when: - status: - - success - - failure -- name: Clean up exec runner storage (post) - commands: - - set -u - - chmod -R u+rw $WORKSPACE_DIR - - rm -rf $WORKSPACE_DIR/go $WORKSPACE_DIR/.ssh - environment: - WORKSPACE_DIR: /tmp/push-build-darwin-amd64 -- name: Send Slack notification (exec) +- name: Delegate build to GitHub + image: golang:1.18-alpine + pull: if-not-exists commands: - - |2 - - export DRONE_BUILD_LINK="${DRONE_SYSTEM_PROTO}://${DRONE_SYSTEM_HOSTNAME}/${DRONE_REPO_OWNER}/${DRONE_REPO_NAME}/${DRONE_BUILD_NUMBER}" - export GOOS=$(go env GOOS) - export GOARCH=$(go env GOARCH) - - |2- - - curl -sL -X POST -H 'Content-type: application/json' --data "{\"text\":\"Warning: \`${GOOS}-${GOARCH}\` artifact build failed for [\`${DRONE_REPO_NAME}\`] - please investigate immediately!\nBranch: \`${DRONE_BRANCH}\`\nCommit: \`${DRONE_COMMIT_SHA}\`\nLink: $DRONE_BUILD_LINK\"}" $SLACK_WEBHOOK_DEV_TELEPORT + - cd "/go/src/github.com/gravitational/teleport/build.assets/tooling" + - 'go run ./cmd/gh-trigger-workflow -owner ${DRONE_REPO_OWNER} -repo teleport.e + -tag-workflow -timeout 1h0m0s -workflow release-mac-amd64.yaml -workflow-ref=${DRONE_BRANCH} + -input oss-teleport-repo=${DRONE_REPO} -input oss-teleport-ref=${DRONE_COMMIT} + -input "build-packages=false" -input "release-artifacts=false" ' environment: - SLACK_WEBHOOK_DEV_TELEPORT: + GHA_APP_KEY: + from_secret: GITHUB_WORKFLOW_APP_PRIVATE_KEY +- name: Send Slack notification + image: plugins/slack + settings: + webhook: from_secret: SLACK_WEBHOOK_DEV_TELEPORT + template: + - | + *{{#success build.status}}✔{{ else }}✘{{/success}} {{ uppercasefirst build.status }}: Build #{{ build.number }}* (type: `{{ build.event }}`) + `${DRONE_STAGE_NAME}` artifact build failed. + *Warning:* This is a genuine failure to build the Teleport binary from `{{ build.branch }}` (likely due to a bad merge or commit) and should be investigated immediately. + Commit: + Branch: + Author: + <{{ build.link }}|Visit Drone build page ↗> when: status: - failure +image_pull_secrets: +- DOCKERHUB_CREDENTIALS --- ################################################ @@ -1366,8 +1259,9 @@ steps: commands: - cd "/go/src/github.com/gravitational/teleport/build.assets/tooling" - 'go run ./cmd/gh-trigger-workflow -owner ${DRONE_REPO_OWNER} -repo teleport.e - -workflow release-linux-arm64.yml -workflow-ref=${DRONE_BRANCH} -input oss-teleport-repo=${DRONE_REPO} - -input oss-teleport-ref=${DRONE_COMMIT} -input "upload-artifacts=false" ' + -tag-workflow -timeout 1h0m0s -workflow release-linux-arm64.yml -workflow-ref=${DRONE_BRANCH} + -input oss-teleport-repo=${DRONE_REPO} -input oss-teleport-ref=${DRONE_COMMIT} + -input "upload-artifacts=false" ' environment: GHA_APP_KEY: from_secret: GITHUB_WORKFLOW_APP_PRIVATE_KEY @@ -4422,11 +4316,11 @@ image_pull_secrets: ################################################ # Generated using dronegen, do not edit by hand! # Use 'make dronegen' to update. -# Generated at dronegen/mac.go (main.newDarwinPipeline) +# Generated at dronegen/gha.go (main.ghaBuildPipeline) ################################################ kind: pipeline -type: exec +type: kubernetes name: build-darwin-amd64 trigger: event: @@ -4439,132 +4333,165 @@ trigger: include: - gravitational/* workspace: - path: /tmp/build-darwin-amd64 -platform: - os: darwin - arch: amd64 + path: /go clone: disable: true -depends_on: -- clean-up-previous-build -concurrency: - limit: 1 steps: -- name: Set up exec runner storage +- name: Check out code + image: docker:git + pull: if-not-exists + commands: + - mkdir -pv "/go/src/github.com/gravitational/teleport" + - cd "/go/src/github.com/gravitational/teleport" + - git init + - git remote add origin ${DRONE_REMOTE_URL} + - git fetch origin --tags + - git checkout -qf "${DRONE_COMMIT_SHA}" + - mkdir -m 0700 /root/.ssh && echo "$GITHUB_PRIVATE_KEY" > /root/.ssh/id_rsa && + chmod 600 /root/.ssh/id_rsa + - ssh-keyscan -H github.com > /root/.ssh/known_hosts 2>/dev/null && chmod 600 /root/.ssh/known_hosts + - git submodule update --init e + - mkdir -pv /go/cache + - rm -f /root/.ssh/id_rsa + environment: + GITHUB_PRIVATE_KEY: + from_secret: GITHUB_PRIVATE_KEY +- name: Delegate build to GitHub + image: golang:1.18-alpine + pull: if-not-exists commands: - - set -u - - mkdir -p $WORKSPACE_DIR - - chmod -R u+rw $WORKSPACE_DIR - - rm -rf $WORKSPACE_DIR/go $WORKSPACE_DIR/.ssh + - cd "/go/src/github.com/gravitational/teleport/build.assets/tooling" + - 'go run ./cmd/gh-trigger-workflow -owner ${DRONE_REPO_OWNER} -repo teleport.e + -tag-workflow -timeout 1h0m0s -workflow release-mac-amd64.yaml -workflow-ref=${DRONE_TAG} + -input oss-teleport-repo=${DRONE_REPO} -input oss-teleport-ref=${DRONE_TAG} -input + "build-packages=true" -input "release-artifacts=true" ' environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64 + GHA_APP_KEY: + from_secret: GITHUB_WORKFLOW_APP_PRIVATE_KEY +- name: Send Slack notification + image: plugins/slack + settings: + webhook: + from_secret: SLACK_WEBHOOK_DEV_TELEPORT + template: + - | + *{{#success build.status}}✔{{ else }}✘{{/success}} {{ uppercasefirst build.status }}: Build #{{ build.number }}* (type: `{{ build.event }}`) + `${DRONE_STAGE_NAME}` artifact build failed. + *Warning:* This is a genuine failure to build the Teleport binary from `{{ build.branch }}` (likely due to a bad merge or commit) and should be investigated immediately. + Commit: + Branch: + Author: + <{{ build.link }}|Visit Drone build page ↗> + when: + status: + - failure +image_pull_secrets: +- DOCKERHUB_CREDENTIALS + +--- +################################################ +# Generated using dronegen, do not edit by hand! +# Use 'make dronegen' to update. +# Generated at dronegen/tag.go (main.tagPipeline) +################################################ + +kind: pipeline +type: kubernetes +name: build-linux-arm +environment: + BUILDBOX_VERSION: teleport12 + RUNTIME: go1.20.3 +trigger: + event: + include: + - tag + ref: + include: + - refs/tags/v* + repo: + include: + - gravitational/* +workspace: + path: /go +clone: + disable: true +depends_on: +- clean-up-previous-build +steps: - name: Check out code + image: docker:git + pull: if-not-exists commands: - - set -u - - mkdir -p $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport + - mkdir -p /go/src/github.com/gravitational/teleport + - cd /go/src/github.com/gravitational/teleport - git clone https://github.com/gravitational/${DRONE_REPO_NAME}.git . - git checkout ${DRONE_TAG:-$DRONE_COMMIT} - - mkdir -m 0700 $WORKSPACE_DIR/.ssh && echo "$GITHUB_PRIVATE_KEY" > $WORKSPACE_DIR/.ssh/id_rsa - && chmod 600 $WORKSPACE_DIR/.ssh/id_rsa - - ssh-keyscan -H github.com > $WORKSPACE_DIR/.ssh/known_hosts 2>/dev/null - - chmod 600 $WORKSPACE_DIR/.ssh/known_hosts - - GIT_SSH_COMMAND='ssh -i $WORKSPACE_DIR/.ssh/id_rsa -o UserKnownHostsFile=$WORKSPACE_DIR/.ssh/known_hosts - -F /dev/null' git submodule update --init e - - rm -rf $WORKSPACE_DIR/.ssh - - mkdir -p $WORKSPACE_DIR/go/cache - - mkdir -p $WORKSPACE_DIR/go/artifacts - - echo "${DRONE_TAG##v}" > $WORKSPACE_DIR/go/.version.txt - - cat $WORKSPACE_DIR/go/.version.txt + - mkdir -m 0700 /root/.ssh && echo -n "$GITHUB_PRIVATE_KEY" > /root/.ssh/id_rsa + && chmod 600 /root/.ssh/id_rsa + - ssh-keyscan -H github.com > /root/.ssh/known_hosts 2>/dev/null && chmod 600 /root/.ssh/known_hosts + - git submodule update --init e + - rm -f /root/.ssh/id_rsa + - mkdir -p /go/cache /go/artifacts + - |- + VERSION=$(egrep ^VERSION Makefile | cut -d= -f2) + if [ "$$VERSION" != "${DRONE_TAG##v}" ]; then + echo "Mismatch between Makefile version: $$VERSION and git tag: $DRONE_TAG" + exit 1 + fi + echo "$$VERSION" > /go/.version.txt environment: GITHUB_PRIVATE_KEY: from_secret: GITHUB_PRIVATE_KEY - WORKSPACE_DIR: /tmp/build-darwin-amd64 -- name: Install Go Toolchain +- name: Wait for docker + image: docker + pull: if-not-exists commands: - - set -u - - mkdir -p /tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains - - curl --silent -O https://dl.google.com/go/$RUNTIME.darwin-amd64.tar.gz - - tar -C /tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains -xzf $RUNTIME.darwin-amd64.tar.gz - - rm -rf $RUNTIME.darwin-amd64.tar.gz - environment: - RUNTIME: go1.20.3 -- name: Install Rust Toolchain - commands: - - set -u - - export PATH=/Users/$(whoami)/.cargo/bin:$PATH - - mkdir -p /tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains - - export RUST_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets - print-rust-version) - - export CARGO_HOME=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains/cargo - - export RUST_HOME=$CARGO_HOME - - export RUSTUP_HOME=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains/rustup - - rustup toolchain install $RUST_VERSION - environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64 -- name: Install Node Toolchain + - timeout 30s /bin/sh -c 'while [ ! -S /var/run/docker.sock ]; do sleep 1; done' + - printenv DOCKERHUB_PASSWORD | docker login -u="$DOCKERHUB_USERNAME" --password-stdin + environment: + DOCKERHUB_PASSWORD: + from_secret: DOCKERHUB_READONLY_TOKEN + DOCKERHUB_USERNAME: + from_secret: DOCKERHUB_USERNAME + volumes: + - name: dockersock + path: /var/run + - name: dockerconfig + path: /root/.docker +- name: Build artifacts + image: docker + pull: if-not-exists commands: - - set -u - - export NODE_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets - print-node-version) - - export TOOLCHAIN_DIR=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains - - export NODE_DIR=$TOOLCHAIN_DIR/node-v$NODE_VERSION-darwin-x64 - - mkdir -p $TOOLCHAIN_DIR - - curl --silent -O https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-darwin-x64.tar.gz - - tar -C $TOOLCHAIN_DIR -xzf node-v$NODE_VERSION-darwin-x64.tar.gz - - rm -f node-v$NODE_VERSION-darwin-x64.tar.gz - - export PATH=$NODE_DIR/bin:$PATH - - corepack enable yarn - - echo Node reporting version $(node --version) - - echo Yarn reporting version $(yarn --version) - environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64 -- name: Build Mac artifacts (binaries) - commands: - - set -u - - export HOME=/Users/$(whoami) - - export TOOLCHAIN_DIR=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains - - security unlock-keychain -p $${BUILDBOX_PASSWORD} login.keychain - - security find-identity -v - - export NODE_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets - print-node-version) - - export NODE_HOME=$TOOLCHAIN_DIR/node-v$NODE_VERSION-darwin-x64 - - export PATH=$NODE_HOME/bin:$PATH - - export RUST_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets - print-rust-version) - - export CARGO_HOME=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains/cargo - - export RUST_HOME=$CARGO_HOME - - export RUSTUP_HOME=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains/rustup - - export PATH=$CARGO_HOME/bin:/Users/build/.cargo/bin:$PATH - - rustup override set $RUST_VERSION - - export PATH=$TOOLCHAIN_DIR/go/bin:$PATH - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - build.assets/build-fido2-macos.sh build - - export PKG_CONFIG_PATH="$(build.assets/build-fido2-macos.sh pkg_config_path)" - - make clean release OS=$OS ARCH=$ARCH FIDO2=yes TOUCHID=yes PIV=yes - environment: - APPLE_PASSWORD: - from_secret: APPLE_PASSWORD - APPLE_USERNAME: - from_secret: APPLE_USERNAME - ARCH: amd64 - BUILDBOX_PASSWORD: - from_secret: BUILDBOX_PASSWORD - GOCACHE: /tmp/build-darwin-amd64/go/cache - GOPATH: /tmp/build-darwin-amd64/go - OS: darwin - WORKSPACE_DIR: /tmp/build-darwin-amd64 -- name: Copy Mac artifacts - commands: - - set -u - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - cp teleport*.tar.gz $WORKSPACE_DIR/go/artifacts - - cp e/teleport-ent*.tar.gz $WORKSPACE_DIR/go/artifacts - - cd $WORKSPACE_DIR/go/artifacts && for FILE in teleport*.tar.gz; do shasum -a 256 - $FILE > $FILE.sha256; done && ls -l - environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64 + - apk add --no-cache make + - chown -R $UID:$GID /go + - cd /go/src/github.com/gravitational/teleport + - make -C build.assets release-arm + environment: + ARCH: arm + GID: "1000" + GOCACHE: /go/cache + GOPATH: /go + OS: linux + UID: "1000" + volumes: + - name: dockersock + path: /var/run + - name: dockerconfig + path: /root/.docker +- name: Copy artifacts + image: docker + pull: if-not-exists + commands: + - cd /go/src/github.com/gravitational/teleport + - find . -maxdepth 1 -iname "teleport*.tar.gz" -print -exec cp {} /go/artifacts + \; + - find e/ -maxdepth 1 -iname "teleport*.tar.gz" -print -exec cp {} /go/artifacts + \; + - cd /go/artifacts && for FILE in teleport*.tar.gz; do sha256sum $FILE > $FILE.sha256; + done && ls -l - name: Assume AWS Role + image: amazon/aws-cli + pull: if-not-exists commands: - aws sts get-caller-identity - |- @@ -4574,7 +4501,7 @@ steps: --role-session-name $(echo "drone-${DRONE_REPO}-${DRONE_BUILD_NUMBER}" | sed "s|/|-|g") \ --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" \ --output text) \ - > /tmp/build-darwin-amd64/credentials + > /root/.aws/credentials - unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY - aws sts get-caller-identity --profile default environment: @@ -4584,19 +4511,25 @@ steps: from_secret: AWS_ROLE AWS_SECRET_ACCESS_KEY: from_secret: AWS_SECRET_ACCESS_KEY - AWS_SHARED_CREDENTIALS_FILE: /tmp/build-darwin-amd64/credentials + volumes: + - name: awsconfig + path: /root/.aws - name: Upload to S3 + image: amazon/aws-cli + pull: if-not-exists commands: - - set -u - - cd $WORKSPACE_DIR/go/artifacts + - cd /go/artifacts/ - aws s3 sync . s3://$AWS_S3_BUCKET/teleport/tag/${DRONE_TAG##v} environment: AWS_REGION: us-west-2 AWS_S3_BUCKET: from_secret: AWS_S3_BUCKET - AWS_SHARED_CREDENTIALS_FILE: /tmp/build-darwin-amd64/credentials - WORKSPACE_DIR: /tmp/build-darwin-amd64 + volumes: + - name: awsconfig + path: /root/.aws - name: Register artifacts + image: docker + pull: if-not-exists commands: - WORKSPACE_DIR=$${WORKSPACE_DIR:-/} - VERSION=$(cat "$WORKSPACE_DIR/go/.version.txt") @@ -4614,7 +4547,7 @@ steps: [ -f "$file.sha256" ] || continue name="$(basename "$file" | sed -E 's/(-|_)v?[0-9].*$//')" # extract part before -vX.Y.Z - description="MacOS Intel" + description="Linux ARMv7 (32-bit)" products="$name" if [ "$name" = "tsh" ]; then products="teleport teleport-ent" @@ -4637,655 +4570,40 @@ steps: release_params="$release_params -F releaseId=$product@$VERSION" done - curl $CREDENTIALS --fail -o /dev/null -F description="$description" -F os="darwin" -F arch="amd64" -F "file=@$file" -F "sha256=$shasum" $release_params "$RELEASES_HOST/assets"; + curl $CREDENTIALS --fail -o /dev/null -F description="$description" -F os="linux" -F arch="arm" -F "file=@$file" -F "sha256=$shasum" $release_params "$RELEASES_HOST/assets"; done environment: RELEASES_CERT: from_secret: RELEASES_CERT RELEASES_KEY: from_secret: RELEASES_KEY - WORKSPACE_DIR: /tmp/build-darwin-amd64 -- name: Clean up toolchains (post) - commands: - - set -u - - export PATH=/Users/$(whoami)/.cargo/bin:$PATH - - export CARGO_HOME=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains/cargo - - export RUST_HOME=$CARGO_HOME - - export RUSTUP_HOME=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains/rustup - - export RUST_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets - print-rust-version) - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - rustup override unset - - rustup toolchain uninstall $RUST_VERSION - - rm -rf /tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED - environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64 - when: - status: - - success - - failure -- name: Clean up exec runner storage (post) - commands: - - set -u - - chmod -R u+rw $WORKSPACE_DIR - - rm -rf $WORKSPACE_DIR/go $WORKSPACE_DIR/.ssh - environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64 +services: +- name: Start Docker + image: docker:dind + privileged: true + volumes: + - name: dockersock + path: /var/run +volumes: +- name: awsconfig + temp: {} +- name: dockersock + temp: {} +- name: dockerconfig + temp: {} +image_pull_secrets: +- DOCKERHUB_CREDENTIALS --- ################################################ # Generated using dronegen, do not edit by hand! # Use 'make dronegen' to update. -# Generated at dronegen/mac.go (main.newDarwinPipeline) +# Generated at dronegen/gha.go (main.ghaBuildPipeline) ################################################ kind: pipeline -type: exec -name: build-darwin-amd64-pkg -trigger: - event: - include: - - tag - ref: - include: - - refs/tags/v* - repo: - include: - - gravitational/* -workspace: - path: /tmp/build-darwin-amd64-pkg -platform: - os: darwin - arch: amd64 -clone: - disable: true -depends_on: -- build-darwin-amd64 -concurrency: - limit: 1 -steps: -- name: Set up exec runner storage - commands: - - set -u - - mkdir -p $WORKSPACE_DIR - - chmod -R u+rw $WORKSPACE_DIR - - rm -rf $WORKSPACE_DIR/go $WORKSPACE_DIR/.ssh - environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64-pkg -- name: Check out code - commands: - - set -u - - mkdir -p $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - git clone https://github.com/gravitational/${DRONE_REPO_NAME}.git . - - git checkout ${DRONE_TAG:-$DRONE_COMMIT} - - mkdir -m 0700 $WORKSPACE_DIR/.ssh && echo "$GITHUB_PRIVATE_KEY" > $WORKSPACE_DIR/.ssh/id_rsa - && chmod 600 $WORKSPACE_DIR/.ssh/id_rsa - - ssh-keyscan -H github.com > $WORKSPACE_DIR/.ssh/known_hosts 2>/dev/null - - chmod 600 $WORKSPACE_DIR/.ssh/known_hosts - - GIT_SSH_COMMAND='ssh -i $WORKSPACE_DIR/.ssh/id_rsa -o UserKnownHostsFile=$WORKSPACE_DIR/.ssh/known_hosts - -F /dev/null' git submodule update --init e - - rm -rf $WORKSPACE_DIR/.ssh - - mkdir -p $WORKSPACE_DIR/go/cache - - mkdir -p $WORKSPACE_DIR/go/artifacts - - echo "${DRONE_TAG##v}" > $WORKSPACE_DIR/go/.version.txt - - cat $WORKSPACE_DIR/go/.version.txt - environment: - GITHUB_PRIVATE_KEY: - from_secret: GITHUB_PRIVATE_KEY - WORKSPACE_DIR: /tmp/build-darwin-amd64-pkg -- name: Assume AWS Role - commands: - - aws sts get-caller-identity - - |- - printf "[default]\naws_access_key_id = %s\naws_secret_access_key = %s\naws_session_token = %s\n" \ - $(aws sts assume-role \ - --role-arn "$AWS_ROLE" \ - --role-session-name $(echo "drone-${DRONE_REPO}-${DRONE_BUILD_NUMBER}" | sed "s|/|-|g") \ - --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" \ - --output text) \ - > /tmp/build-darwin-amd64-pkg/credentials - - unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY - - aws sts get-caller-identity --profile default - environment: - AWS_ACCESS_KEY_ID: - from_secret: AWS_ACCESS_KEY_ID - AWS_ROLE: - from_secret: AWS_ROLE - AWS_SECRET_ACCESS_KEY: - from_secret: AWS_SECRET_ACCESS_KEY - AWS_SHARED_CREDENTIALS_FILE: /tmp/build-darwin-amd64-pkg/credentials -- name: Download built tarball artifacts from S3 - commands: - - set -u - - export VERSION=$(cat $WORKSPACE_DIR/go/.version.txt) - - export S3_PATH="tag/$${DRONE_TAG##v}/" - - aws s3 cp s3://$AWS_S3_BUCKET/teleport/$${S3_PATH}teleport-v$${VERSION}-darwin-amd64-bin.tar.gz - $WORKSPACE_DIR/go/artifacts/ - - aws s3 cp s3://$AWS_S3_BUCKET/teleport/$${S3_PATH}teleport-ent-v$${VERSION}-darwin-amd64-bin.tar.gz - $WORKSPACE_DIR/go/artifacts/ - environment: - AWS_REGION: us-west-2 - AWS_S3_BUCKET: - from_secret: AWS_S3_BUCKET - AWS_SHARED_CREDENTIALS_FILE: /tmp/build-darwin-amd64-pkg/credentials - GITHUB_PRIVATE_KEY: - from_secret: GITHUB_PRIVATE_KEY - WORKSPACE_DIR: /tmp/build-darwin-amd64-pkg -- name: Build Mac pkg release artifacts - commands: - - set -u - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - export VERSION=$(cat $WORKSPACE_DIR/go/.version.txt) - - export HOME=/Users/build - - security unlock-keychain -p $${BUILDBOX_PASSWORD} login.keychain - - security find-identity -v - - make pkg OS=$OS ARCH=$ARCH - environment: - APPLE_PASSWORD: - from_secret: APPLE_PASSWORD - APPLE_USERNAME: - from_secret: APPLE_USERNAME - ARCH: amd64 - BUILDBOX_PASSWORD: - from_secret: BUILDBOX_PASSWORD - ENT_TARBALL_PATH: /tmp/build-darwin-amd64-pkg/go/artifacts - OS: darwin - OSS_TARBALL_PATH: /tmp/build-darwin-amd64-pkg/go/artifacts - WORKSPACE_DIR: /tmp/build-darwin-amd64-pkg -- name: Copy Mac pkg artifacts - commands: - - set -u - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - rm -rf $WORKSPACE_DIR/go/artifacts/*.tar.gz - - cp build/teleport*.pkg e/build/teleport-ent*.pkg $WORKSPACE_DIR/go/artifacts/ - - cd $WORKSPACE_DIR/go/artifacts && for FILE in *.pkg; do shasum -a 256 $FILE > - $FILE.sha256; done && ls -l - environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64-pkg -- name: Upload to S3 - commands: - - set -u - - cd $WORKSPACE_DIR/go/artifacts - - aws s3 sync . s3://$AWS_S3_BUCKET/teleport/tag/${DRONE_TAG##v} - environment: - AWS_REGION: us-west-2 - AWS_S3_BUCKET: - from_secret: AWS_S3_BUCKET - AWS_SHARED_CREDENTIALS_FILE: /tmp/build-darwin-amd64-pkg/credentials - WORKSPACE_DIR: /tmp/build-darwin-amd64-pkg -- name: Register artifacts - commands: - - WORKSPACE_DIR=$${WORKSPACE_DIR:-/} - - VERSION=$(cat "$WORKSPACE_DIR/go/.version.txt") - - RELEASES_HOST='https://releases-prod.platform.teleport.sh' - - echo "$RELEASES_CERT" | base64 -d > "$WORKSPACE_DIR/releases.crt" - - echo "$RELEASES_KEY" | base64 -d > "$WORKSPACE_DIR/releases.key" - - trap "rm -f '$WORKSPACE_DIR/releases.crt' '$WORKSPACE_DIR/releases.key'" EXIT - - CREDENTIALS="--cert $WORKSPACE_DIR/releases.crt --key $WORKSPACE_DIR/releases.key" - - which curl || apk add --no-cache curl - - |- - cd "$WORKSPACE_DIR/go/artifacts" - find . -type f ! -iname '*.sha256' ! -iname '*-unsigned.zip*' | while read -r file; do - # Skip files that are not results of this build - # (e.g. tarballs from which OS packages are made) - [ -f "$file.sha256" ] || continue - - name="$(basename "$file" | sed -E 's/(-|_)v?[0-9].*$//')" # extract part before -vX.Y.Z - description="MacOS Intel .pkg installer" - products="$name" - if [ "$name" = "tsh" ]; then - products="teleport teleport-ent" - elif [ "$name" = "Teleport Connect" -o "$name" = "teleport-connect" ]; then - description="Teleport Connect" - products="teleport teleport-ent" - fi - shasum="$(cat "$file.sha256" | cut -d ' ' -f 1)" - - release_params="" # List of "-F releaseId=XXX" parameters to curl - - for product in $products; do - status_code=$(curl $CREDENTIALS -o "$WORKSPACE_DIR/curl_out.txt" -w "%{http_code}" -F "product=$product" -F "version=$VERSION" -F notesMd="# Teleport $VERSION" -F status=draft "$RELEASES_HOST/releases") - if [ $status_code -ne 200 ] && [ $status_code -ne 409 ]; then - echo "curl HTTP status: $status_code" - cat $WORKSPACE_DIR/curl_out.txt - exit 1 - fi - - release_params="$release_params -F releaseId=$product@$VERSION" - done - - curl $CREDENTIALS --fail -o /dev/null -F description="$description" -F os="darwin" -F arch="amd64" -F "file=@$file" -F "sha256=$shasum" $release_params "$RELEASES_HOST/assets"; - done - environment: - RELEASES_CERT: - from_secret: RELEASES_CERT - RELEASES_KEY: - from_secret: RELEASES_KEY - WORKSPACE_DIR: /tmp/build-darwin-amd64-pkg -- name: Clean up exec runner storage (post) - commands: - - set -u - - chmod -R u+rw $WORKSPACE_DIR - - rm -rf $WORKSPACE_DIR/go $WORKSPACE_DIR/.ssh - environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64-pkg - ---- -################################################ -# Generated using dronegen, do not edit by hand! -# Use 'make dronegen' to update. -# Generated at dronegen/mac.go (main.newDarwinPipeline) -################################################ - -kind: pipeline -type: exec -name: build-darwin-amd64-pkg-tsh -trigger: - event: - include: - - tag - ref: - include: - - refs/tags/v* - repo: - include: - - gravitational/* -workspace: - path: /tmp/build-darwin-amd64-pkg-tsh -platform: - os: darwin - arch: amd64 -clone: - disable: true -depends_on: -- build-darwin-amd64 -concurrency: - limit: 1 -steps: -- name: Set up exec runner storage - commands: - - set -u - - mkdir -p $WORKSPACE_DIR - - chmod -R u+rw $WORKSPACE_DIR - - rm -rf $WORKSPACE_DIR/go $WORKSPACE_DIR/.ssh - environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64-pkg-tsh -- name: Check out code - commands: - - set -u - - mkdir -p $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - git clone https://github.com/gravitational/${DRONE_REPO_NAME}.git . - - git checkout ${DRONE_TAG:-$DRONE_COMMIT} - - mkdir -m 0700 $WORKSPACE_DIR/.ssh && echo "$GITHUB_PRIVATE_KEY" > $WORKSPACE_DIR/.ssh/id_rsa - && chmod 600 $WORKSPACE_DIR/.ssh/id_rsa - - ssh-keyscan -H github.com > $WORKSPACE_DIR/.ssh/known_hosts 2>/dev/null - - chmod 600 $WORKSPACE_DIR/.ssh/known_hosts - - GIT_SSH_COMMAND='ssh -i $WORKSPACE_DIR/.ssh/id_rsa -o UserKnownHostsFile=$WORKSPACE_DIR/.ssh/known_hosts - -F /dev/null' git submodule update --init e - - rm -rf $WORKSPACE_DIR/.ssh - - mkdir -p $WORKSPACE_DIR/go/cache - - mkdir -p $WORKSPACE_DIR/go/artifacts - - echo "${DRONE_TAG##v}" > $WORKSPACE_DIR/go/.version.txt - - cat $WORKSPACE_DIR/go/.version.txt - environment: - GITHUB_PRIVATE_KEY: - from_secret: GITHUB_PRIVATE_KEY - WORKSPACE_DIR: /tmp/build-darwin-amd64-pkg-tsh -- name: Assume AWS Role - commands: - - aws sts get-caller-identity - - |- - printf "[default]\naws_access_key_id = %s\naws_secret_access_key = %s\naws_session_token = %s\n" \ - $(aws sts assume-role \ - --role-arn "$AWS_ROLE" \ - --role-session-name $(echo "drone-${DRONE_REPO}-${DRONE_BUILD_NUMBER}" | sed "s|/|-|g") \ - --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" \ - --output text) \ - > /tmp/build-darwin-amd64-pkg-tsh/credentials - - unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY - - aws sts get-caller-identity --profile default - environment: - AWS_ACCESS_KEY_ID: - from_secret: AWS_ACCESS_KEY_ID - AWS_ROLE: - from_secret: AWS_ROLE - AWS_SECRET_ACCESS_KEY: - from_secret: AWS_SECRET_ACCESS_KEY - AWS_SHARED_CREDENTIALS_FILE: /tmp/build-darwin-amd64-pkg-tsh/credentials -- name: Download built tarball artifacts from S3 - commands: - - set -u - - export VERSION=$(cat $WORKSPACE_DIR/go/.version.txt) - - export S3_PATH="tag/$${DRONE_TAG##v}/" - - aws s3 cp s3://$AWS_S3_BUCKET/teleport/$${S3_PATH}teleport-v$${VERSION}-darwin-amd64-bin.tar.gz - $WORKSPACE_DIR/go/artifacts/ - - aws s3 cp s3://$AWS_S3_BUCKET/teleport/$${S3_PATH}teleport-ent-v$${VERSION}-darwin-amd64-bin.tar.gz - $WORKSPACE_DIR/go/artifacts/ - environment: - AWS_REGION: us-west-2 - AWS_S3_BUCKET: - from_secret: AWS_S3_BUCKET - AWS_SHARED_CREDENTIALS_FILE: /tmp/build-darwin-amd64-pkg-tsh/credentials - GITHUB_PRIVATE_KEY: - from_secret: GITHUB_PRIVATE_KEY - WORKSPACE_DIR: /tmp/build-darwin-amd64-pkg-tsh -- name: Build Mac pkg release artifacts - commands: - - set -u - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - export VERSION=$(cat $WORKSPACE_DIR/go/.version.txt) - - export HOME=/Users/build - - security unlock-keychain -p $${BUILDBOX_PASSWORD} login.keychain - - security find-identity -v - - make pkg-tsh OS=$OS ARCH=$ARCH - environment: - APPLE_PASSWORD: - from_secret: APPLE_PASSWORD - APPLE_USERNAME: - from_secret: APPLE_USERNAME - ARCH: amd64 - BUILDBOX_PASSWORD: - from_secret: BUILDBOX_PASSWORD - ENT_TARBALL_PATH: /tmp/build-darwin-amd64-pkg-tsh/go/artifacts - OS: darwin - OSS_TARBALL_PATH: /tmp/build-darwin-amd64-pkg-tsh/go/artifacts - WORKSPACE_DIR: /tmp/build-darwin-amd64-pkg-tsh -- name: Copy Mac pkg artifacts - commands: - - set -u - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - rm -rf $WORKSPACE_DIR/go/artifacts/*.tar.gz - - cp build/tsh*.pkg $WORKSPACE_DIR/go/artifacts/ - - cd $WORKSPACE_DIR/go/artifacts && for FILE in *.pkg; do shasum -a 256 $FILE > - $FILE.sha256; done && ls -l - environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64-pkg-tsh -- name: Upload to S3 - commands: - - set -u - - cd $WORKSPACE_DIR/go/artifacts - - aws s3 sync . s3://$AWS_S3_BUCKET/teleport/tag/${DRONE_TAG##v} - environment: - AWS_REGION: us-west-2 - AWS_S3_BUCKET: - from_secret: AWS_S3_BUCKET - AWS_SHARED_CREDENTIALS_FILE: /tmp/build-darwin-amd64-pkg-tsh/credentials - WORKSPACE_DIR: /tmp/build-darwin-amd64-pkg-tsh -- name: Register artifacts - commands: - - WORKSPACE_DIR=$${WORKSPACE_DIR:-/} - - VERSION=$(cat "$WORKSPACE_DIR/go/.version.txt") - - RELEASES_HOST='https://releases-prod.platform.teleport.sh' - - echo "$RELEASES_CERT" | base64 -d > "$WORKSPACE_DIR/releases.crt" - - echo "$RELEASES_KEY" | base64 -d > "$WORKSPACE_DIR/releases.key" - - trap "rm -f '$WORKSPACE_DIR/releases.crt' '$WORKSPACE_DIR/releases.key'" EXIT - - CREDENTIALS="--cert $WORKSPACE_DIR/releases.crt --key $WORKSPACE_DIR/releases.key" - - which curl || apk add --no-cache curl - - |- - cd "$WORKSPACE_DIR/go/artifacts" - find . -type f ! -iname '*.sha256' ! -iname '*-unsigned.zip*' | while read -r file; do - # Skip files that are not results of this build - # (e.g. tarballs from which OS packages are made) - [ -f "$file.sha256" ] || continue - - name="$(basename "$file" | sed -E 's/(-|_)v?[0-9].*$//')" # extract part before -vX.Y.Z - description="MacOS Intel .pkg installer (tsh client only)" - products="$name" - if [ "$name" = "tsh" ]; then - products="teleport teleport-ent" - elif [ "$name" = "Teleport Connect" -o "$name" = "teleport-connect" ]; then - description="Teleport Connect" - products="teleport teleport-ent" - fi - shasum="$(cat "$file.sha256" | cut -d ' ' -f 1)" - - release_params="" # List of "-F releaseId=XXX" parameters to curl - - for product in $products; do - status_code=$(curl $CREDENTIALS -o "$WORKSPACE_DIR/curl_out.txt" -w "%{http_code}" -F "product=$product" -F "version=$VERSION" -F notesMd="# Teleport $VERSION" -F status=draft "$RELEASES_HOST/releases") - if [ $status_code -ne 200 ] && [ $status_code -ne 409 ]; then - echo "curl HTTP status: $status_code" - cat $WORKSPACE_DIR/curl_out.txt - exit 1 - fi - - release_params="$release_params -F releaseId=$product@$VERSION" - done - - curl $CREDENTIALS --fail -o /dev/null -F description="$description" -F os="darwin" -F arch="amd64" -F "file=@$file" -F "sha256=$shasum" $release_params "$RELEASES_HOST/assets"; - done - environment: - RELEASES_CERT: - from_secret: RELEASES_CERT - RELEASES_KEY: - from_secret: RELEASES_KEY - WORKSPACE_DIR: /tmp/build-darwin-amd64-pkg-tsh -- name: Clean up exec runner storage (post) - commands: - - set -u - - chmod -R u+rw $WORKSPACE_DIR - - rm -rf $WORKSPACE_DIR/go $WORKSPACE_DIR/.ssh - environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64-pkg-tsh - ---- -################################################ -# Generated using dronegen, do not edit by hand! -# Use 'make dronegen' to update. -# Generated at dronegen/tag.go (main.tagPipeline) -################################################ - -kind: pipeline -type: kubernetes -name: build-linux-arm -environment: - BUILDBOX_VERSION: teleport12 - RUNTIME: go1.20.3 -trigger: - event: - include: - - tag - ref: - include: - - refs/tags/v* - repo: - include: - - gravitational/* -workspace: - path: /go -clone: - disable: true -depends_on: -- clean-up-previous-build -steps: -- name: Check out code - image: docker:git - pull: if-not-exists - commands: - - mkdir -p /go/src/github.com/gravitational/teleport - - cd /go/src/github.com/gravitational/teleport - - git clone https://github.com/gravitational/${DRONE_REPO_NAME}.git . - - git checkout ${DRONE_TAG:-$DRONE_COMMIT} - - mkdir -m 0700 /root/.ssh && echo -n "$GITHUB_PRIVATE_KEY" > /root/.ssh/id_rsa - && chmod 600 /root/.ssh/id_rsa - - ssh-keyscan -H github.com > /root/.ssh/known_hosts 2>/dev/null && chmod 600 /root/.ssh/known_hosts - - git submodule update --init e - - rm -f /root/.ssh/id_rsa - - mkdir -p /go/cache /go/artifacts - - |- - VERSION=$(egrep ^VERSION Makefile | cut -d= -f2) - if [ "$$VERSION" != "${DRONE_TAG##v}" ]; then - echo "Mismatch between Makefile version: $$VERSION and git tag: $DRONE_TAG" - exit 1 - fi - echo "$$VERSION" > /go/.version.txt - environment: - GITHUB_PRIVATE_KEY: - from_secret: GITHUB_PRIVATE_KEY -- name: Wait for docker - image: docker - pull: if-not-exists - commands: - - timeout 30s /bin/sh -c 'while [ ! -S /var/run/docker.sock ]; do sleep 1; done' - - printenv DOCKERHUB_PASSWORD | docker login -u="$DOCKERHUB_USERNAME" --password-stdin - environment: - DOCKERHUB_PASSWORD: - from_secret: DOCKERHUB_READONLY_TOKEN - DOCKERHUB_USERNAME: - from_secret: DOCKERHUB_USERNAME - volumes: - - name: dockersock - path: /var/run - - name: dockerconfig - path: /root/.docker -- name: Build artifacts - image: docker - pull: if-not-exists - commands: - - apk add --no-cache make - - chown -R $UID:$GID /go - - cd /go/src/github.com/gravitational/teleport - - make -C build.assets release-arm - environment: - ARCH: arm - GID: "1000" - GOCACHE: /go/cache - GOPATH: /go - OS: linux - UID: "1000" - volumes: - - name: dockersock - path: /var/run - - name: dockerconfig - path: /root/.docker -- name: Copy artifacts - image: docker - pull: if-not-exists - commands: - - cd /go/src/github.com/gravitational/teleport - - find . -maxdepth 1 -iname "teleport*.tar.gz" -print -exec cp {} /go/artifacts - \; - - find e/ -maxdepth 1 -iname "teleport*.tar.gz" -print -exec cp {} /go/artifacts - \; - - cd /go/artifacts && for FILE in teleport*.tar.gz; do sha256sum $FILE > $FILE.sha256; - done && ls -l -- name: Assume AWS Role - image: amazon/aws-cli - pull: if-not-exists - commands: - - aws sts get-caller-identity - - |- - printf "[default]\naws_access_key_id = %s\naws_secret_access_key = %s\naws_session_token = %s\n" \ - $(aws sts assume-role \ - --role-arn "$AWS_ROLE" \ - --role-session-name $(echo "drone-${DRONE_REPO}-${DRONE_BUILD_NUMBER}" | sed "s|/|-|g") \ - --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" \ - --output text) \ - > /root/.aws/credentials - - unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY - - aws sts get-caller-identity --profile default - environment: - AWS_ACCESS_KEY_ID: - from_secret: AWS_ACCESS_KEY_ID - AWS_ROLE: - from_secret: AWS_ROLE - AWS_SECRET_ACCESS_KEY: - from_secret: AWS_SECRET_ACCESS_KEY - volumes: - - name: awsconfig - path: /root/.aws -- name: Upload to S3 - image: amazon/aws-cli - pull: if-not-exists - commands: - - cd /go/artifacts/ - - aws s3 sync . s3://$AWS_S3_BUCKET/teleport/tag/${DRONE_TAG##v} - environment: - AWS_REGION: us-west-2 - AWS_S3_BUCKET: - from_secret: AWS_S3_BUCKET - volumes: - - name: awsconfig - path: /root/.aws -- name: Register artifacts - image: docker - pull: if-not-exists - commands: - - WORKSPACE_DIR=$${WORKSPACE_DIR:-/} - - VERSION=$(cat "$WORKSPACE_DIR/go/.version.txt") - - RELEASES_HOST='https://releases-prod.platform.teleport.sh' - - echo "$RELEASES_CERT" | base64 -d > "$WORKSPACE_DIR/releases.crt" - - echo "$RELEASES_KEY" | base64 -d > "$WORKSPACE_DIR/releases.key" - - trap "rm -f '$WORKSPACE_DIR/releases.crt' '$WORKSPACE_DIR/releases.key'" EXIT - - CREDENTIALS="--cert $WORKSPACE_DIR/releases.crt --key $WORKSPACE_DIR/releases.key" - - which curl || apk add --no-cache curl - - |- - cd "$WORKSPACE_DIR/go/artifacts" - find . -type f ! -iname '*.sha256' ! -iname '*-unsigned.zip*' | while read -r file; do - # Skip files that are not results of this build - # (e.g. tarballs from which OS packages are made) - [ -f "$file.sha256" ] || continue - - name="$(basename "$file" | sed -E 's/(-|_)v?[0-9].*$//')" # extract part before -vX.Y.Z - description="Linux ARMv7 (32-bit)" - products="$name" - if [ "$name" = "tsh" ]; then - products="teleport teleport-ent" - elif [ "$name" = "Teleport Connect" -o "$name" = "teleport-connect" ]; then - description="Teleport Connect" - products="teleport teleport-ent" - fi - shasum="$(cat "$file.sha256" | cut -d ' ' -f 1)" - - release_params="" # List of "-F releaseId=XXX" parameters to curl - - for product in $products; do - status_code=$(curl $CREDENTIALS -o "$WORKSPACE_DIR/curl_out.txt" -w "%{http_code}" -F "product=$product" -F "version=$VERSION" -F notesMd="# Teleport $VERSION" -F status=draft "$RELEASES_HOST/releases") - if [ $status_code -ne 200 ] && [ $status_code -ne 409 ]; then - echo "curl HTTP status: $status_code" - cat $WORKSPACE_DIR/curl_out.txt - exit 1 - fi - - release_params="$release_params -F releaseId=$product@$VERSION" - done - - curl $CREDENTIALS --fail -o /dev/null -F description="$description" -F os="linux" -F arch="arm" -F "file=@$file" -F "sha256=$shasum" $release_params "$RELEASES_HOST/assets"; - done - environment: - RELEASES_CERT: - from_secret: RELEASES_CERT - RELEASES_KEY: - from_secret: RELEASES_KEY -services: -- name: Start Docker - image: docker:dind - privileged: true - volumes: - - name: dockersock - path: /var/run -volumes: -- name: awsconfig - temp: {} -- name: dockersock - temp: {} -- name: dockerconfig - temp: {} -image_pull_secrets: -- DOCKERHUB_CREDENTIALS - ---- -################################################ -# Generated using dronegen, do not edit by hand! -# Use 'make dronegen' to update. -# Generated at dronegen/gha.go (main.ghaBuildPipeline) -################################################ - -kind: pipeline -type: kubernetes -name: build-linux-arm64 +type: kubernetes +name: build-linux-arm64 trigger: event: include: @@ -5328,8 +4646,9 @@ steps: commands: - cd "/go/src/github.com/gravitational/teleport/build.assets/tooling" - 'go run ./cmd/gh-trigger-workflow -owner ${DRONE_REPO_OWNER} -repo teleport.e - -workflow release-linux-arm64.yml -workflow-ref=${DRONE_TAG} -input oss-teleport-repo=${DRONE_REPO} - -input oss-teleport-ref=${DRONE_TAG} -input "upload-artifacts=true" ' + -tag-workflow -timeout 1h0m0s -workflow release-linux-arm64.yml -workflow-ref=${DRONE_TAG} + -input oss-teleport-repo=${DRONE_REPO} -input oss-teleport-ref=${DRONE_TAG} -input + "upload-artifacts=true" ' environment: GHA_APP_KEY: from_secret: GITHUB_WORKFLOW_APP_PRIVATE_KEY @@ -8201,249 +7520,14 @@ steps: commands: - cd "/go/src/github.com/gravitational/teleport/build.assets/tooling" - 'go run ./cmd/gh-trigger-workflow -owner ${DRONE_REPO_OWNER} -repo teleport.e - -workflow promote-teleport-oci-distroless.yml -workflow-ref=${DRONE_TAG} -input - "release-source-tag=${DRONE_TAG}" ' + -tag-workflow -timeout 1h0m0s -workflow promote-teleport-oci-distroless.yml -workflow-ref=${DRONE_TAG} + -input "release-source-tag=${DRONE_TAG}" ' environment: GHA_APP_KEY: from_secret: GITHUB_WORKFLOW_APP_PRIVATE_KEY image_pull_secrets: - DOCKERHUB_CREDENTIALS ---- -################################################ -# Generated using dronegen, do not edit by hand! -# Use 'make dronegen' to update. -# Generated at dronegen/mac.go (main.newDarwinPipeline) -################################################ - -kind: pipeline -type: exec -name: build-darwin-amd64-connect -trigger: - event: - include: - - tag - ref: - include: - - refs/tags/v* - repo: - include: - - gravitational/* -workspace: - path: /tmp/build-darwin-amd64-connect -platform: - os: darwin - arch: amd64 -clone: - disable: true -depends_on: -- build-darwin-amd64-pkg-tsh -concurrency: - limit: 1 -steps: -- name: Set up exec runner storage - commands: - - set -u - - mkdir -p $WORKSPACE_DIR - - chmod -R u+rw $WORKSPACE_DIR - - rm -rf $WORKSPACE_DIR/go $WORKSPACE_DIR/.ssh - environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64-connect -- name: Check out code - commands: - - set -u - - mkdir -p $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - git clone https://github.com/gravitational/${DRONE_REPO_NAME}.git . - - git checkout ${DRONE_TAG:-$DRONE_COMMIT} - - mkdir -m 0700 $WORKSPACE_DIR/.ssh && echo "$GITHUB_PRIVATE_KEY" > $WORKSPACE_DIR/.ssh/id_rsa - && chmod 600 $WORKSPACE_DIR/.ssh/id_rsa - - ssh-keyscan -H github.com > $WORKSPACE_DIR/.ssh/known_hosts 2>/dev/null - - chmod 600 $WORKSPACE_DIR/.ssh/known_hosts - - GIT_SSH_COMMAND='ssh -i $WORKSPACE_DIR/.ssh/id_rsa -o UserKnownHostsFile=$WORKSPACE_DIR/.ssh/known_hosts - -F /dev/null' git submodule update --init e - - rm -rf $WORKSPACE_DIR/.ssh - - mkdir -p $WORKSPACE_DIR/go/cache - - mkdir -p $WORKSPACE_DIR/go/artifacts - - echo "${DRONE_TAG##v}" > $WORKSPACE_DIR/go/.version.txt - - cat $WORKSPACE_DIR/go/.version.txt - environment: - GITHUB_PRIVATE_KEY: - from_secret: GITHUB_PRIVATE_KEY - WORKSPACE_DIR: /tmp/build-darwin-amd64-connect -- name: Install Node Toolchain - commands: - - set -u - - export NODE_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets - print-node-version) - - export TOOLCHAIN_DIR=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains - - export NODE_DIR=$TOOLCHAIN_DIR/node-v$NODE_VERSION-darwin-x64 - - mkdir -p $TOOLCHAIN_DIR - - curl --silent -O https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-darwin-x64.tar.gz - - tar -C $TOOLCHAIN_DIR -xzf node-v$NODE_VERSION-darwin-x64.tar.gz - - rm -f node-v$NODE_VERSION-darwin-x64.tar.gz - - export PATH=$NODE_DIR/bin:$PATH - - corepack enable yarn - - echo Node reporting version $(node --version) - - echo Yarn reporting version $(yarn --version) - environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64-connect -- name: Assume AWS Role - commands: - - aws sts get-caller-identity - - |- - printf "[default]\naws_access_key_id = %s\naws_secret_access_key = %s\naws_session_token = %s\n" \ - $(aws sts assume-role \ - --role-arn "$AWS_ROLE" \ - --role-session-name $(echo "drone-${DRONE_REPO}-${DRONE_BUILD_NUMBER}" | sed "s|/|-|g") \ - --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" \ - --output text) \ - > /tmp/build-darwin-amd64-connect/credentials - - unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY - - aws sts get-caller-identity --profile default - environment: - AWS_ACCESS_KEY_ID: - from_secret: AWS_ACCESS_KEY_ID - AWS_ROLE: - from_secret: AWS_ROLE - AWS_SECRET_ACCESS_KEY: - from_secret: AWS_SECRET_ACCESS_KEY - AWS_SHARED_CREDENTIALS_FILE: /tmp/build-darwin-amd64-connect/credentials -- name: Download tsh.pkg artifact from S3 - commands: - - set -u - - export VERSION=$(cat $WORKSPACE_DIR/go/.version.txt) - - export S3_PATH="tag/$${DRONE_TAG##v}/" - - aws s3 cp s3://$AWS_S3_BUCKET/teleport/$${S3_PATH}tsh-$${VERSION}.pkg $WORKSPACE_DIR/go/src/github.com/gravitational/ - environment: - AWS_REGION: us-west-2 - AWS_S3_BUCKET: - from_secret: AWS_S3_BUCKET - AWS_SHARED_CREDENTIALS_FILE: /tmp/build-darwin-amd64-connect/credentials - GITHUB_PRIVATE_KEY: - from_secret: GITHUB_PRIVATE_KEY - WORKSPACE_DIR: /tmp/build-darwin-amd64-connect -- name: Build Mac artifacts (Teleport Connect) - commands: - - set -u - - export HOME=/Users/$(whoami) - - export TOOLCHAIN_DIR=/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED/toolchains - - security unlock-keychain -p $${BUILDBOX_PASSWORD} login.keychain - - security find-identity -v - - export NODE_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets - print-node-version) - - export NODE_HOME=$TOOLCHAIN_DIR/node-v$NODE_VERSION-darwin-x64 - - export PATH=$NODE_HOME/bin:$PATH - - export VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - print-version) - - export BUILD_NUMBER=$DRONE_BUILD_NUMBER - - security unlock-keychain -p $${BUILDBOX_PASSWORD} login.keychain - - security find-identity -v - - export CSC_NAME=0FFD3E3413AB4C599C53FBB1D8CA690915E33D83 - - cd $WORKSPACE_DIR/go/src/github.com/gravitational - - pkgutil --expand-full tsh-$${VERSION}.pkg tsh - - export CONNECT_TSH_APP_PATH=$WORKSPACE_DIR/go/src/github.com/gravitational/tsh/Payload/tsh.app - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport - - yarn install && yarn build-term && yarn package-term -c.extraMetadata.version=$VERSION - environment: - APPLE_PASSWORD: - from_secret: APPLE_PASSWORD - APPLE_USERNAME: - from_secret: APPLE_USERNAME - ARCH: amd64 - BUILDBOX_PASSWORD: - from_secret: BUILDBOX_PASSWORD - GOCACHE: /tmp/build-darwin-amd64-connect/go/cache - GOPATH: /tmp/build-darwin-amd64-connect/go - OS: darwin - WORKSPACE_DIR: /tmp/build-darwin-amd64-connect -- name: Copy dmg artifact - commands: - - set -u - - cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/web/packages/teleterm/build/release - - cp *.dmg $WORKSPACE_DIR/go/artifacts - - cd $WORKSPACE_DIR/go/artifacts && for FILE in *.dmg; do shasum -a 256 "$FILE" - > "$FILE.sha256"; done && ls -l - environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64-connect -- name: Upload to S3 - commands: - - set -u - - cd $WORKSPACE_DIR/go/artifacts - - aws s3 sync . s3://$AWS_S3_BUCKET/teleport/tag/${DRONE_TAG##v} - environment: - AWS_REGION: us-west-2 - AWS_S3_BUCKET: - from_secret: AWS_S3_BUCKET - AWS_SHARED_CREDENTIALS_FILE: /tmp/build-darwin-amd64-connect/credentials - WORKSPACE_DIR: /tmp/build-darwin-amd64-connect -- name: Register artifact - commands: - - WORKSPACE_DIR=$${WORKSPACE_DIR:-/} - - VERSION=$(cat "$WORKSPACE_DIR/go/.version.txt") - - RELEASES_HOST='https://releases-prod.platform.teleport.sh' - - echo "$RELEASES_CERT" | base64 -d > "$WORKSPACE_DIR/releases.crt" - - echo "$RELEASES_KEY" | base64 -d > "$WORKSPACE_DIR/releases.key" - - trap "rm -f '$WORKSPACE_DIR/releases.crt' '$WORKSPACE_DIR/releases.key'" EXIT - - CREDENTIALS="--cert $WORKSPACE_DIR/releases.crt --key $WORKSPACE_DIR/releases.key" - - which curl || apk add --no-cache curl - - |- - cd "$WORKSPACE_DIR/go/artifacts" - find . -type f ! -iname '*.sha256' ! -iname '*-unsigned.zip*' | while read -r file; do - # Skip files that are not results of this build - # (e.g. tarballs from which OS packages are made) - [ -f "$file.sha256" ] || continue - - name="$(basename "$file" | sed -E 's/(-|_)v?[0-9].*$//')" # extract part before -vX.Y.Z - description="MacOS Intel" - products="$name" - if [ "$name" = "tsh" ]; then - products="teleport teleport-ent" - elif [ "$name" = "Teleport Connect" -o "$name" = "teleport-connect" ]; then - description="Teleport Connect" - products="teleport teleport-ent" - fi - shasum="$(cat "$file.sha256" | cut -d ' ' -f 1)" - - release_params="" # List of "-F releaseId=XXX" parameters to curl - - for product in $products; do - status_code=$(curl $CREDENTIALS -o "$WORKSPACE_DIR/curl_out.txt" -w "%{http_code}" -F "product=$product" -F "version=$VERSION" -F notesMd="# Teleport $VERSION" -F status=draft "$RELEASES_HOST/releases") - if [ $status_code -ne 200 ] && [ $status_code -ne 409 ]; then - echo "curl HTTP status: $status_code" - cat $WORKSPACE_DIR/curl_out.txt - exit 1 - fi - - release_params="$release_params -F releaseId=$product@$VERSION" - done - - curl $CREDENTIALS --fail -o /dev/null -F description="$description" -F os="darwin" -F arch="amd64" -F "file=@$file" -F "sha256=$shasum" $release_params "$RELEASES_HOST/assets"; - done - environment: - RELEASES_CERT: - from_secret: RELEASES_CERT - RELEASES_KEY: - from_secret: RELEASES_KEY - WORKSPACE_DIR: /tmp/build-darwin-amd64-connect -- name: Clean up toolchains (post) - commands: - - set -u - - rm -rf /tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED - environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64-connect - when: - status: - - success - - failure -- name: Clean up exec runner storage (post) - commands: - - set -u - - chmod -R u+rw $WORKSPACE_DIR - - rm -rf $WORKSPACE_DIR/go $WORKSPACE_DIR/.ssh - environment: - WORKSPACE_DIR: /tmp/build-darwin-amd64-connect - --- ################################################ # Generated using dronegen, do not edit by hand! @@ -9788,8 +8872,8 @@ steps: commands: - cd "/go/src/github.com/gravitational/teleport/build.assets/tooling" - 'go run ./cmd/gh-trigger-workflow -owner ${DRONE_REPO_OWNER} -repo teleport.e - -workflow release-teleport-oci-distroless.yml -workflow-ref=${DRONE_TAG} -input - oss-teleport-repo=${DRONE_REPO} -input oss-teleport-ref=${DRONE_TAG} ' + -tag-workflow -timeout 1h0m0s -workflow release-teleport-oci-distroless.yml -workflow-ref=${DRONE_TAG} + -input oss-teleport-repo=${DRONE_REPO} -input oss-teleport-ref=${DRONE_TAG} ' environment: GHA_APP_KEY: from_secret: GITHUB_WORKFLOW_APP_PRIVATE_KEY @@ -21149,6 +20233,6 @@ image_pull_secrets: - DOCKERHUB_CREDENTIALS --- kind: signature -hmac: f1a3f39a5c2824f1512119f7eb1ab0c490d27734c5051f159b5a6a54a9f7ab38 +hmac: efcec364da8bb65ddadb67002357347ebb40ea036ac8753441502480962d2821 ... diff --git a/Makefile b/Makefile index b16052b7e3fc8..d3b7f85357261 100644 --- a/Makefile +++ b/Makefile @@ -429,6 +429,8 @@ build-archive: release-unix: clean full build-archive @if [ -f e/Makefile ]; then $(MAKE) -C e release; fi +include darwin-signing.mk + .PHONY: release-darwin-unsigned release-darwin-unsigned: RELEASE:=$(RELEASE)-unsigned release-darwin-unsigned: clean full build-archive @@ -436,12 +438,7 @@ release-darwin-unsigned: clean full build-archive .PHONY: release-darwin release-darwin: ABSOLUTE_BINARY_PATHS:=$(addprefix $(CURDIR)/,$(BINARIES)) release-darwin: release-darwin-unsigned - # Only run if Apple username/pass for notarization are provided - if [ -n "$$APPLE_USERNAME" -a -n "$$APPLE_PASSWORD" ]; then \ - cd ./build.assets/tooling/ && \ - go run ./cmd/notarize-apple-binaries/*.go \ - --log-level=debug $(ABSOLUTE_BINARY_PATHS); \ - fi + $(NOTARIZE_BINARIES) $(MAKE) build-archive @if [ -f e/Makefile ]; then $(MAKE) -C e release; fi @@ -505,6 +502,28 @@ release-windows: release-windows-unsigned rm -rf teleport/ @echo "---> Created $(RELEASE).zip." +# +# make release-connect produces a release package of Teleport Connect. +# It is used only for MacOS releases. Windows releases do not use this +# Makefile. Linux uses the `teleterm` target in build.assets/Makefile. +# +# Only export the CSC_NAME (developer key ID) when the recipe is run, so +# that we do not shell out and run the `security` command if not necessary. +# +# Either CONNECT_TSH_BIN_PATH or CONNECT_TSH_APP_PATH environment variable +# should be defined for the `yarn package-term` command to succeed. CI sets +# this appropriately depending on whether a push build is running, or a +# proper release (a proper release needs the APP_PATH as that points to +# the complete signed package). See web/packages/teleterm/README.md for +# details. +# +.PHONY: release-connect +release-connect: + $(eval export CSC_NAME) + yarn install --frozen-lockfile + yarn build-term + yarn package-term -c.extraMetadata.version=$(VERSION) + # # Remove trailing whitespace in all markdown files under docs/. # @@ -1068,18 +1087,20 @@ endif # build .pkg .PHONY: pkg pkg: + $(eval export DEVELOPER_ID_APPLICATION DEVELOPER_ID_INSTALLER) mkdir -p $(BUILDDIR)/ cp ./build.assets/build-package.sh ./build.assets/build-common.sh $(BUILDDIR)/ chmod +x $(BUILDDIR)/build-package.sh # arch and runtime are currently ignored on OS X # we pass them through for consistency - they will be dropped by the build script - cd $(BUILDDIR) && ./build-package.sh -t oss -v $(VERSION) -p pkg -a $(ARCH) $(RUNTIME_SECTION) $(TARBALL_PATH_SECTION) + cd $(BUILDDIR) && ./build-package.sh -t oss -v $(VERSION) -p pkg -b $(TELEPORT_BUNDLEID) -a $(ARCH) $(RUNTIME_SECTION) $(TARBALL_PATH_SECTION) if [ -f e/Makefile ]; then $(MAKE) -C e pkg; fi # build tsh client-only .pkg .PHONY: pkg-tsh pkg-tsh: - ./build.assets/build-pkg-tsh.sh -t oss -v $(VERSION) $(TARBALL_PATH_SECTION) + $(eval export DEVELOPER_ID_APPLICATION DEVELOPER_ID_INSTALLER) + ./build.assets/build-pkg-tsh.sh -t oss -v $(VERSION) -b $(TSH_BUNDLEID) $(TARBALL_PATH_SECTION) mkdir -p $(BUILDDIR)/ mv tsh*.pkg* $(BUILDDIR)/ diff --git a/build.assets/build-common.sh b/build.assets/build-common.sh index 841e2bffb8659..7549bcc39d2a6 100644 --- a/build.assets/build-common.sh +++ b/build.assets/build-common.sh @@ -6,25 +6,6 @@ # Toggle this via flags in your main script. DRY_RUN_PREFIX='' -# Teleport / tsh certificates/info. -# Used by other scripts. -#shellcheck disable=SC2034 -readonly DEVELOPER_ID_APPLICATION='0FFD3E3413AB4C599C53FBB1D8CA690915E33D83' -#shellcheck disable=SC2034 -readonly DEVELOPER_ID_INSTALLER='82B625AD327C241B378A54B4B254BB08CE71B5DF' -readonly TEAMID='QH8AA5B8UP' -#shellcheck disable=SC2034 -readonly TSH_BUNDLEID="$TEAMID.com.gravitational.teleport.tsh" -#shellcheck disable=SC2034 -readonly TSH_SKELETON='tsh' # relative to build.assets/macos/ - -# tshdev certs/info. -#readonly DEVELOPER_ID_APPLICATION='A5604F285B0957134EA099AC515BD9E0787228AC' -#readonly DEVELOPER_ID_INSTALLER='C1A831A974DF69563432C87A4979F7982DD91FBE' -#readonly TEAMID='K497G57PDJ' -#readonly TSH_BUNDLEID="$TEAMID.com.goteleport.tshdev" -#readonly TSH_SKELETON='tshdev' # relative to build.assets/macos/ - # TARBALL_CACHE is used by find_or_fetch_tarball. readonly TARBALL_CACHE=/tmp/teleport-tarballs diff --git a/build.assets/build-package.sh b/build.assets/build-package.sh index 5e89ce80dc9ce..77d347b9518b3 100755 --- a/build.assets/build-package.sh +++ b/build.assets/build-package.sh @@ -2,7 +2,7 @@ set -e usage() { - echo "Usage: $(basename $0) [-t ] [-v ] [-p ] <-a [amd64/x86_64]|[386/i386]|arm|arm64> <-r fips> <-s tarball source dir>" 1>&2 + echo "Usage: $(basename $0) [-t ] [-v ] [-p ] [-b ] <-a [amd64/x86_64]|[386/i386]|arm|arm64> <-r fips> <-s tarball source dir>" 1>&2 exit 1 } @@ -11,7 +11,7 @@ usage() { #shellcheck disable=SC1091 . "$(dirname "$0")/build-common.sh" -while getopts ":t:v:p:a:r:s:n" o; do +while getopts ":t:v:p:a:r:s:b:n" o; do case "${o}" in t) t=${OPTARG} @@ -35,6 +35,9 @@ while getopts ":t:v:p:a:r:s:n" o; do s) s=${OPTARG} ;; + b) + b=${OPTARG} + ;; n) # Dry-run mode. # Only affects parts of the script, use at your own peril! @@ -120,6 +123,11 @@ else usage fi + if [[ -n "${b:-}" ]]; then + echo "bundle ID parameter can only be used for OS X packages" + exit 6 + fi + # set docker image appropriately if [[ "${PACKAGE_TYPE}" == "deb" ]]; then DOCKER_IMAGE="public.ecr.aws/gravitational/fpm:debian8" @@ -197,7 +205,7 @@ fi if [[ "${PACKAGE_TYPE}" == "pkg" ]]; then SIGN_PKG="true" FILE_LIST="${TAR_PATH}/tsh ${TAR_PATH}/tctl ${TAR_PATH}/teleport ${TAR_PATH}/tbot" - BUNDLE_ID="com.gravitational.teleport" + BUNDLE_ID="${b:-com.gravitational.teleport}" if [[ "${TELEPORT_TYPE}" == "ent" ]]; then PKG_FILENAME="teleport-ent-${TELEPORT_VERSION}.${PACKAGE_TYPE}" else diff --git a/build.assets/build-pkg-tsh.sh b/build.assets/build-pkg-tsh.sh index 3704a276980f3..125ca4080ebd0 100755 --- a/build.assets/build-pkg-tsh.sh +++ b/build.assets/build-pkg-tsh.sh @@ -5,9 +5,10 @@ set -eu TELEPORT_TYPE='' # -t, oss or ent TELEPORT_VERSION='' # -v, version, without leading 'v' TARBALL_DIRECTORY='' # -s +BUNDLEID="${TSH_BUNDLEID}" usage() { - log "Usage: $0 -t oss|eng -v version [-s tarball_directory] [-n]" + log "Usage: $0 -t oss|eng -v version [-s tarball_directory] [-b bundle_id] [-n]" } # make_non_relocatable_plist changes the default component plist of the $root @@ -34,7 +35,7 @@ main() { . "$buildassets/build-common.sh" local opt='' - while getopts "t:v:s:n" opt; do + while getopts "t:v:s:b:n" opt; do case "$opt" in t) if [[ "$OPTARG" != "oss" && "$OPTARG" != "ent" ]]; then @@ -54,6 +55,9 @@ main() { fi TARBALL_DIRECTORY="$OPTARG" ;; + b) + BUNDLEID="$OPTARG" + ;; n) DRY_RUN_PREFIX='echo + ' # declared by build-common.sh ;; @@ -75,6 +79,12 @@ main() { exit 1 fi + if [[ -z "${BUNDLEID}" ]]; then + echo "No bundle ID specified. Either set TSH_BUNDLEID or use -b bundle_id" + usage + exit 1 + fi + # Verify environment varibles. if [[ "${APPLE_USERNAME:-}" == "" ]]; then echo "\ @@ -89,6 +99,20 @@ password created by APPLE_USERNAME" exit 1 fi + if [[ -z "${DEVELOPER_ID_APPLICATION}" ]]; then + echo "\ +The DEVELOPER_ID_APPLICATION environment variable needs to be set to the hash\ +of the key to sign applications" + exit 1 + fi + + if [[ -z "${DEVELOPER_ID_INSTALLER}" ]]; then + echo "\ +The DEVELOPER_ID_INSTALLER environment variable needs to be set to the hash\ +of the key to sign packages" + exit 1 + fi + # Use similar find-or-download logic as build-package.sh for compatibility # purposes. local ent='' @@ -134,7 +158,7 @@ password created by APPLE_USERNAME" $DRY_RUN_PREFIX codesign -f \ -o kill,hard,runtime \ -s "$DEVELOPER_ID_APPLICATION" \ - -i "$TSH_BUNDLEID" \ + -i "$BUNDLEID" \ --entitlements "$skel"/tsh*.entitlements \ --timestamp \ "$target" @@ -149,7 +173,7 @@ password created by APPLE_USERNAME" pkgbuild \ --root "$pkg_root" \ --component-plist "$pkg_component_plist" \ - --identifier "$TSH_BUNDLEID" \ + --identifier "$BUNDLEID" \ --version "v$TELEPORT_VERSION" \ --install-location /Applications \ --scripts "$pkg_scripts" \ @@ -166,7 +190,7 @@ password created by APPLE_USERNAME" fi # Notarize. - notarize "$target" "$TEAMID" "$TSH_BUNDLEID" + notarize "$target" "$TEAMID" "$BUNDLEID" # Copy resulting package to $PWD, generate hashes. mv "$target" . diff --git a/build.assets/keychain-setup.sh b/build.assets/keychain-setup.sh new file mode 100755 index 0000000000000..6e7962d9799dd --- /dev/null +++ b/build.assets/keychain-setup.sh @@ -0,0 +1,223 @@ +#!/bin/bash +# +# keychain-setup.sh creates a MacOS keychain for application binary signing +# and for installer package signing. Each use separate keys that need to +# be loaded into a keychain. +# +# This is intended to be called from CI to set up the keychain for signing +# and notarizing MacOS binaries and packages/images. It can be called manually +# during development if you have the development keys and notarization +# username/password in your environment. +# +# This is MVP - the intention is to write all the keychain management, signing +# and notarizing as a Go program. +# +#----------------------------------------------------------------------------- +usage() { + cat <...} +Available options: + -a take base64-encoded application key from + -a @ take application key from + -A take password for application key from + -i take base64-encoded installation key from + -i @ take installation key from + -I take password for installation key from + -k create .keychain (default "build") + -p use on keychain (default "insecure") + -v verbose. Print commands before running them + -n dry run. Do not run commands, just print them +EOF +} + +#----------------------------------------------------------------------------- +APPLICATION_KEY_FILE='' +APPLICATION_KEY_PASSWORD='' +INSTALLER_KEY_FILE='' +INSTALLER_KEY_PASSWORD='' +KEYCHAIN='build' +KEYCHAIN_PASSWORD='insecure' # Does not need to be secret on CI, as the keychain is removed after. +VERBOSE=false +DRY_RUN=false + +# This should be an array of filenames, but bash on MacOS (3.2.57) seems to unset +# the array before the EXIT trap fires and we get an unset variable error when +# trying to remove the files listed in the array. +tmpfiles='' + +#----------------------------------------------------------------------------- +main() { + set -euo pipefail + + # Always remove temp files, even if dry run + trap 'DRY_RUN=false rm -f ${tmpfiles}' EXIT + parse_args "$@" + + create_keychain "${KEYCHAIN}" "${KEYCHAIN_PASSWORD}" + add_key "${APPLICATION_KEY_FILE}" "${APPLICATION_KEY_PASSWORD}" "${KEYCHAIN}" "${KEYCHAIN_PASSWORD}" + add_key "${INSTALLER_KEY_FILE}" "${INSTALLER_KEY_PASSWORD}" "${KEYCHAIN}" "${KEYCHAIN_PASSWORD}" +} + +# Create a keychain ($1) with a password ($2) and put it on the user keychain +# search path. +create_keychain() { + local keychain="$1" password="$2" + run security create-keychain -p "${password}" "${keychain}" + run security unlock-keychain -p "${password}" "${keychain}" + run security set-keychain-settings "${keychain}" # keep keychain unlocked + + # Add the new keychain to the search path, otherwise codesign does not find the keys + local kpath + kpath="$(security list-keychains -d user | sed 's/.*"\([^"]*\)"/\1/')" + # shellcheck disable=SC2086 # Double quote to prevent globbing and word splitting. + # We want word splitting on ${kpath} + run security list-keychains -d user -s "${keychain}" ${kpath} +} + +# Add a key from a file ($1) protected with a passphrase ($2) to a keychain ($3) +# protected with a password ($4). This is to allow `/usr/bin/codesign` and +# `/usr/bin/productsign` to access the key. +# If the key file name is empty, add_key returns without doing anything. +add_key() { + local keyfile="$1" passphrase="$2" keychain="$3" keychain_password="$4" + if [[ -z "${keyfile}" ]]; then + return 0 + fi + run security import "${keyfile}" \ + -k "${keychain}" -P "${passphrase}" \ + -T /usr/bin/codesign \ + -T /usr/bin/productsign + # Set ACLs so the key can be used for code signing. + # Note: This selects all the signing keys (-s) in the keychain to be usable + # for code signing. Not a problem because the keychain is just for that only + # and only contains the keys we've just added. + run security set-key-partition-list \ + -S 'apple-tool:,apple:,codesign:' \ + -s -k "${keychain_password}" "${keychain}" +} + +#----------------------------------------------------------------------------- +parse_args() { + OPTSTRING=':A:I:a:i:k:np:v' + while getopts "${OPTSTRING}" opt; do + case "${opt}" in + a) + if [[ -n "${APPLICATION_KEY_FILE}" ]]; then + error 'Application key specified multiple times' + fi + APPLICATION_KEY_FILE="$(get_key "${OPTARG}" appkey)" + ;; + A) + require_var "${OPTARG}" + APPLICATION_KEY_PASSWORD="${!OPTARG}" + ;; + i) + if [[ -n "${INSTALLER_KEY_FILE}" ]]; then + error 'Installation key specified multiple times' + fi + INSTALLER_KEY_FILE="$(get_key "${OPTARG}" instkey)" + ;; + I) + require_var "${OPTARG}" + INSTALLER_KEY_PASSWORD="${!OPTARG}" + ;; + k) + KEYCHAIN="${OPTARG}" + ;; + p) + if [[ -z "${OPTARG}" ]]; then + error 'Keychain password cannot be empty' + fi + KEYCHAIN_PASSWORD="${OPTARG}" + ;; + + n) + DRY_RUN=true + ;; + v) + VERBOSE=true + ;; + \?) + error_usage 'Invalid option: -%s\n' "${OPTARG}" >&2 + ;; + :) + error_usage 'Option -%s requires an argument\n' "${OPTARG}" >&2 + ;; + esac + done + shift $((OPTIND - 1)) + + # Keychains have to end with ".keychain". Add it if necessary. + KEYCHAIN="${KEYCHAIN%.keychain}.keychain" +} + +#----------------------------------------------------------------------------- +# Run a command. If $VERBOSE or $DRY_RUN is true, echo the command. If +# $DRY_RUN is true, don't actually run the command, only print it. +run() { + if "${VERBOSE}" || "${DRY_RUN}"; then + echo "$@" + fi + "${DRY_RUN}" || "$@" +} + +# Require an environment variable be set and not empty +require_var() { + local var="$1" + if [[ -z "${!var:-}" ]]; then + error 'env var "%s" unset or empty' "${var}" + fi + return 0 +} + +# Require a file exists +require_file() { + local file="$1" + if ! [[ -f "${file}" ]]; then + error 'File does not exist: %s' "${file}" + fi + return 0 +} + +# Get a key from an argument. If the argument starts with @, the rest is taken +# as a filename containing the key. Otherwise it is taken as an environment +# variable name which contains a base64 encoded key, which is decoded and placed +# into a temp file. The filename of the key is output to stdout. If a temp file +# was created, it will be removed when the script exits. +get_key() { + local key="$1" keytype="$2" fname + # If the key starts with an @, take the rest as a filename. Otherwise + # its an environment variable name. + if [[ "${key}" =~ ^@ ]]; then + fname="${key:1}" + require_file "${fname}" + else + require_var "${key}" + fname="$(mktemp -t "${keytype}").p12" + tmpfiles="${tmpfiles} ${fname}" + printenv "${key}" | base64 --decode > "${fname}" + fi + echo "${fname}" +} + +error() { + # shellcheck disable=SC2059 # (Don't use variables in the printf format string) + # we take a format string arg - the format string IS a variable + printf "$@" >&2 + printf '\n' >&2 + exit 1 +} + +error_usage() { + # shellcheck disable=SC2059 # (Don't use variables in the printf format string) + # we take a format string arg - the format string IS a variable + printf "$@" >&2 + printf '\n' >&2 + usage >&2 + exit 1 +} + +#----------------------------------------------------------------------------- +# Only run main if executed as a script and not sourced. +if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then main "$@"; fi + diff --git a/build.assets/tooling/cmd/notarize-apple-binaries/gon_wrapper.go b/build.assets/tooling/cmd/notarize-apple-binaries/gon_wrapper.go index 52c3dcc0d2560..22b0e7c3e8caf 100644 --- a/build.assets/tooling/cmd/notarize-apple-binaries/gon_wrapper.go +++ b/build.assets/tooling/cmd/notarize-apple-binaries/gon_wrapper.go @@ -31,25 +31,24 @@ import ( "github.com/gravitational/teleport/build.assets/tooling/lib/logging" ) -const ( - DeveloperIdentity string = "0FFD3E3413AB4C599C53FBB1D8CA690915E33D83" - BundleID string = "com.gravitational.teleport" -) - type GonWrapper struct { ctx context.Context logger hclog.Logger AppleUsername string ApplePassword string + DeveloperID string + BundleID string BinaryPaths []string } -func NewGonWrapper(appleUsername, applePassword string, BinaryPaths []string) *GonWrapper { +func NewGonWrapper(appleUsername, applePassword, developerID, bundleID string, BinaryPaths []string) *GonWrapper { return &GonWrapper{ ctx: context.Background(), logger: logging.NewHCLogLogrusAdapter(logrus.StandardLogger()), AppleUsername: appleUsername, ApplePassword: applePassword, + DeveloperID: developerID, + BundleID: bundleID, BinaryPaths: BinaryPaths, } } @@ -79,7 +78,7 @@ func (gw *GonWrapper) SignBinaries() error { gw.logger.Info("Signing binaries %v...", gw.BinaryPaths) err := sign.Sign(gw.ctx, &sign.Options{ Files: gw.BinaryPaths, - Identity: DeveloperIdentity, + Identity: gw.DeveloperID, Logger: gw.logger, }) @@ -119,7 +118,7 @@ func (gw *GonWrapper) NotarizeBinaries(zipPath string) error { gw.logger.Info("Uploading %q to Apple for notarization ticket issuance. This may take awhile...", zipPath) notarizationInfo, err := notarize.Notarize(gw.ctx, ¬arize.Options{ File: zipPath, - BundleId: BundleID, + BundleId: gw.BundleID, Username: gw.AppleUsername, Password: gw.ApplePassword, Logger: gw.logger, diff --git a/build.assets/tooling/cmd/notarize-apple-binaries/main.go b/build.assets/tooling/cmd/notarize-apple-binaries/main.go index 27cbd554f44da..263c094ecd1a9 100644 --- a/build.assets/tooling/cmd/notarize-apple-binaries/main.go +++ b/build.assets/tooling/cmd/notarize-apple-binaries/main.go @@ -27,11 +27,20 @@ import ( const binaryArgName string = "binaries" +// Default values for flags. +// TODO(camh): Remove when all call sites pass the correct values. +const ( + DeveloperIdentity string = "0FFD3E3413AB4C599C53FBB1D8CA690915E33D83" + BundleID string = "com.gravitational.teleport" +) + type Config struct { LogLevel string LogJSON bool AppleUsername string ApplePassword string + DeveloperID string + BundleID string BinaryPaths []string } @@ -41,6 +50,8 @@ func main() { kingpin.Flag("log-json", "Enable JSON logging").Default(fmt.Sprintf("%v", false)).BoolVar(&config.LogJSON) kingpin.Flag("apple-username", "Apple Connect username used for notarization").Required().Envar("APPLE_USERNAME").StringVar(&config.AppleUsername) kingpin.Flag("apple-password", "Apple Connect password used for notarization").Required().Envar("APPLE_PASSWORD").StringVar(&config.ApplePassword) + kingpin.Flag("developer-id", "Key ID for signing binaries").Default(DeveloperIdentity).StringVar(&config.DeveloperID) + kingpin.Flag("bundle-id", "Bundle ID of application").Default(BundleID).StringVar(&config.BundleID) kingpin.Arg(binaryArgName, "Path to Apple binaries for signing and notarization").Required().Action(binaryArgValidatiorAction).ExistingFilesVar(&config.BinaryPaths) kingpin.Parse() @@ -113,7 +124,7 @@ func run(config *Config) error { } NewLoggerConfig(parsedLogLevel, config.LogJSON).setupLogger() - err = NewGonWrapper(config.AppleUsername, config.ApplePassword, config.BinaryPaths).SignAndNotarizeBinaries() + err = NewGonWrapper(config.AppleUsername, config.ApplePassword, config.DeveloperID, config.BundleID, config.BinaryPaths).SignAndNotarizeBinaries() if err != nil { return trace.Wrap(err, "failed to sign and notarize binaries") } diff --git a/darwin-signing.mk b/darwin-signing.mk new file mode 100644 index 0000000000000..face602bfd746 --- /dev/null +++ b/darwin-signing.mk @@ -0,0 +1,111 @@ +# MacOS/Darwin variables for packaging, signing and notarizing. +# +# These are parameterized per environment, with `promote` for official +# releases and `build` for development testing. These environment names +# come from our configuration in GitHub Actions. + +# Default environment name if not specified. This is currently for Drone +# which does not set `ENVIRONMENT_NAME`. Once migrated fully to GitHub +# actions, we should change this to `build` as the default. +ENVIRONMENT_NAME ?= promote + +# Variables defined here are defined with the environment name suffix +# to specify the appropriate value for that environment. The unsuffixed +# names select the appropriate value based on `ENVIRONMENT_NAME` + +# Developer "team" and keys. +# TEAMID is an Apple-assigned identifier for a developer. It has two keys, +# one for signing binaries (application) and one for signing packages/images +# (installer). The keys are identified by name per-environment which we use +# to extract the key IDs. Key names can be view by running `security find-identity`. +# +# NOTE: If you need to export the DEVELOPER_ID_{APPLICATION,INSTALLER} +# variables to the environment for a command, it should be done within the +# recipe containing the command using $(eval export DEVELOPER_ID_APPLICATION ...). +# This is so the `security` shell command is only run to extract the key ID +# if necessary. If exported at the top level, it will run every time `make` +# is run. +# +# e.g. +# pkg: +# $(eval export DEVELOPER_ID_APPLICATION DEVELOPER_ID_INSTALLER) +# ./build.assets/build-package.sh ... +# +TEAMID = $(TEAMID_$(ENVIRONMENT_NAME)) +DEVELOPER_ID_APPLICATION = $(call get_key_id,$(DEVELOPER_KEY_NAME_$(ENVIRONMENT_NAME))) +DEVELOPER_ID_INSTALLER = $(call get_key_id,$(INSTALLER_KEY_NAME_$(ENVIRONMENT_NAME))) + +# CSC_NAME is the key ID for signing used by electron-builder for signing +# Teleport Connect. +CSC_NAME = $(DEVELOPER_ID_APPLICATION) + +# Don't export DEVELOPER_ID_APPLICATION, DEVELOPER_ID_INSTALLER or CSC_NAME as +# it causes them to be evaluated, which shells out to the `security` command. +# They should only be evaluated if used. +unexport CSC_NAME DEVELOPER_ID_APPLICATION DEVELOPER_ID_INSTALLER + +# Bundle IDs identify packages/images. We use different bundle IDs for +# release and development. +TELEPORT_BUNDLEID = $(TELEPORT_BUNDLEID_$(ENVIRONMENT_NAME)) +TSH_BUNDLEID = $(TSH_BUNDLEID_$(ENVIRONMENT_NAME)) + +# TSH_SKELETON is a directory name relative to build.assets/macos/ +TSH_SKELETON = $(TSH_SKELETON_$(ENVIRONMENT_NAME)) + +# --- promote environment +# Key names can be found on https://goteleport.com/security +TEAMID_promote = QH8AA5B8UP +DEVELOPER_KEY_NAME_promote = Developer ID Application: Gravitational Inc. +INSTALLER_KEY_NAME_promote = Developer ID Installer: Gravitational Inc. +TELEPORT_BUNDLEID_promote = com.gravitational.teleport +TSH_BUNDLEID_promote = $(TEAMID).com.gravitational.teleport.tsh +TSH_SKELETON_promote = tsh + +# --- build environment +TEAMID_build = K497G57PDJ +DEVELOPER_KEY_NAME_build = Developer ID Application: Ada Lin +INSTALLER_KEY_NAME_build = Developer ID Installer: Ada Lin +TELEPORT_BUNDLEID_build = com.goteleport.dev +TSH_BUNDLEID_build = $(TEAMID).com.goteleport.tshdev +TSH_SKELETON_build = tshdev + +# --- utility +# Extract application/installer key ID from keychain. This looks at all +# keychains in the search path. It should be used with $(call ...). +# e.g. $(call get_key_id,Key Name goes here) +get_key_id = $(or $(word 2,$(shell $(get_key_id_cmd))), $(missing_key_error)) +get_key_id_cmd = security find-identity -v -s codesigning | grep --fixed-strings --max-count=1 "$(1)" +missing_key_error = $(error Could not find key named "$(1)" in keychain) + +# Dont export missing_key_error or get_key_id as it evaluates them +unexport missing_key_error get_key_id + +# SHOULD_NOTARIZE evalutes to "true" if we should sign and notarize binaries, +# and the empty string if not. We only notarize if APPLE_USERNAME and +# APPLE_PASSWORD are set in the environment. +SHOULD_NOTARIZE = $(if $(and $(APPLE_USERNAME),$(APPLE_PASSWORD)),true) + +# NOTARIZE_BINARIES runs the notarize-apple-binaries tool. It is expected that +# the current working directory is the root of the OSS Teleport repo, so to call +# from the enterprise repo, invoke it as: +# cd .. && $(NOTARIZE_BINARIES) +# It will not run the command if $APPLE_USERNAME or $APPLE_PASSWORD are empty. +# It uses the make $(if ...) construct instead of doing it in the shell so as +# to not evaluate its arguments (DEVELOPER_ID_APPLICATION) if we are not +# goint to use them, preventing a missing key error defined above. +NOTARIZE_BINARIES = $(if $(SHOULD_NOTARIZE),$(notarize_binaries_cmd),$(not_notarizing_cmd)) + +define notarize_binaries_cmd + cd build.assets/tooling && \ + go run ./cmd/notarize-apple-binaries \ + --developer-id=$(DEVELOPER_ID_APPLICATION) \ + --bundle-id=$(TELEPORT_BUNDLEID) \ + --log-level=debug \ + $(ABSOLUTE_BINARY_PATHS) +endef + +not_notarizing_cmd = echo Not notarizing binaries. APPLE_USERNAME or APPLE_PASSWORD not set. + +# Dont export not_notarizing_cmd since it contains DEVELOPER_ID_APPLICATION +# and we do not want that evaluated. +unexport notarize_binaries_cmd diff --git a/dronegen/aws.go b/dronegen/aws.go index 33c925d40ce2f..04176c094bf7c 100644 --- a/dronegen/aws.go +++ b/dronegen/aws.go @@ -38,15 +38,6 @@ type kubernetesRoleSettings struct { append bool } -// macRoleSettings contains the info necessary to assume an AWS role and save the credentials to a path that later steps can use -type macRoleSettings struct { - awsRoleSettings - configPath string - name string - profile string - append bool -} - // kuberentesS3Settings contains all info needed to download from S3 in a kubernetes pipeline type kubernetesS3Settings struct { region string @@ -104,23 +95,6 @@ func kubernetesAssumeAwsRoleStep(s kubernetesRoleSettings) step { } } -// macAssumeAwsRoleStep builds a step to assume an AWS role and save it to a host path that later steps can use -func macAssumeAwsRoleStep(s macRoleSettings) step { - if s.name == "" { - s.name = "Assume AWS Role" - } - return step{ - Name: s.name, - Environment: map[string]value{ - "AWS_ACCESS_KEY_ID": s.awsAccessKeyID, - "AWS_SECRET_ACCESS_KEY": s.awsSecretAccessKey, - "AWS_ROLE": s.role, - "AWS_SHARED_CREDENTIALS_FILE": value{raw: s.configPath}, - }, - Commands: assumeRoleCommands(s.profile, s.configPath, s.append), - } -} - // kubernetesUploadToS3Step generates an S3 upload step func kubernetesUploadToS3Step(s kubernetesS3Settings) step { return step{ diff --git a/dronegen/gha.go b/dronegen/gha.go index 82dc19a0ee3f3..af9082d897e5f 100644 --- a/dronegen/gha.go +++ b/dronegen/gha.go @@ -16,7 +16,11 @@ package main import ( "fmt" + "sort" "strings" + "time" + + "golang.org/x/exp/maps" ) type ghaBuildType struct { @@ -26,6 +30,7 @@ type ghaBuildType struct { ghaWorkflow string srcRefVar string workflowRef string + timeout time.Duration slackOnError bool dependsOn []string inputs map[string]string @@ -41,6 +46,8 @@ func ghaBuildPipeline(b ghaBuildType) pipeline { cmd.WriteString(`go run ./cmd/gh-trigger-workflow `) cmd.WriteString(`-owner ${DRONE_REPO_OWNER} `) cmd.WriteString(`-repo teleport.e `) + cmd.WriteString(`-tag-workflow `) + fmt.Fprintf(&cmd, `-timeout %s `, b.timeout.String()) fmt.Fprintf(&cmd, `-workflow %s `, b.ghaWorkflow) fmt.Fprintf(&cmd, `-workflow-ref=%s `, b.workflowRef) @@ -50,8 +57,12 @@ func ghaBuildPipeline(b ghaBuildType) pipeline { fmt.Fprintf(&cmd, `-input oss-teleport-ref=${%s} `, b.srcRefVar) } - for k, v := range b.inputs { - fmt.Fprintf(&cmd, `-input "%s=%s" `, k, v) + // Sort inputs so the are output in a consistent order to avoid + // spurious changes in the generated drone config. + keys := maps.Keys(b.inputs) + sort.Strings(keys) + for _, k := range keys { + fmt.Fprintf(&cmd, `-input "%s=%s" `, k, b.inputs[k]) } p.Steps = []step{ diff --git a/dronegen/mac.go b/dronegen/mac.go deleted file mode 100644 index fc133e54e6970..0000000000000 --- a/dronegen/mac.go +++ /dev/null @@ -1,623 +0,0 @@ -// Copyright 2021 Gravitational, Inc -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "fmt" - "path" - "path/filepath" -) - -const ( - perBuildDir = "/tmp/build-$DRONE_BUILD_NUMBER-$DRONE_BUILD_CREATED" - perBuildToolchainsDir = perBuildDir + "/toolchains" - perBuildCargoDir = perBuildToolchainsDir + "/cargo" - perBuildRustupDir = perBuildToolchainsDir + "/rustup" -) - -// escapedPreformatted returns expr wrapped in escaped backticks, -// resulting in Slack "preformatted" string, but safe to use in bash -// without triggering the command expansion. -// This is useful for use in Go backtick literals, -// where backticks can not be escaped in any way. -func escapedPreformatted(expr string) string { - return fmt.Sprintf("\\`%s\\`", expr) -} - -func newDarwinPipeline(name string) pipeline { - p := newExecPipeline(name) - p.Workspace.Path = path.Join("/tmp", name) - p.Concurrency.Limit = 1 - p.Platform = platform{OS: "darwin", Arch: "amd64"} - return p -} - -func darwinConnectDmgPipeline() pipeline { - b := buildType{os: "darwin", arch: "amd64"} - toolchainConfig := toolchainConfig{nodejs: true} - artifactConfig := onlyConnectWithBundledTshApp - - p := newDarwinPipeline("build-darwin-amd64-connect") - awsConfigPath := filepath.Join(p.Workspace.Path, "credentials") - p.Trigger = triggerTag - p.DependsOn = []string{"build-darwin-amd64-pkg-tsh"} - p.Steps = []step{ - setUpExecStorageStep(p.Workspace.Path), - { - Name: "Check out code", - Environment: map[string]value{ - "WORKSPACE_DIR": {raw: p.Workspace.Path}, - "GITHUB_PRIVATE_KEY": {fromSecret: "GITHUB_PRIVATE_KEY"}, - }, - Commands: darwinTagCheckoutCommands(artifactConfig), - }, - } - p.Steps = append(p.Steps, - installToolchains(p.Workspace.Path, toolchainConfig)...) - p.Steps = append(p.Steps, []step{ - macAssumeAwsRoleStep(macRoleSettings{ - awsRoleSettings: awsRoleSettings{ - awsAccessKeyID: value{fromSecret: "AWS_ACCESS_KEY_ID"}, - awsSecretAccessKey: value{fromSecret: "AWS_SECRET_ACCESS_KEY"}, - role: value{fromSecret: "AWS_ROLE"}, - }, - configPath: awsConfigPath, - }), - { - Name: "Download tsh.pkg artifact from S3", - Environment: map[string]value{ - "AWS_REGION": {raw: "us-west-2"}, - "AWS_S3_BUCKET": {fromSecret: "AWS_S3_BUCKET"}, - "GITHUB_PRIVATE_KEY": {fromSecret: "GITHUB_PRIVATE_KEY"}, - "WORKSPACE_DIR": {raw: p.Workspace.Path}, - "AWS_SHARED_CREDENTIALS_FILE": {raw: awsConfigPath}, - }, - Commands: darwinConnectDownloadArtifactCommands(), - }, - buildMacArtifactsStep(p.Workspace.Path, b, toolchainConfig, artifactConfig), - { - Name: "Copy dmg artifact", - Environment: map[string]value{ - "WORKSPACE_DIR": {raw: p.Workspace.Path}, - }, - Commands: darwinConnectCopyDmgArtifactCommands(), - }, - { - Name: "Upload to S3", - Environment: map[string]value{ - "AWS_S3_BUCKET": {fromSecret: "AWS_S3_BUCKET"}, - "AWS_REGION": {raw: "us-west-2"}, - "WORKSPACE_DIR": {raw: p.Workspace.Path}, - "AWS_SHARED_CREDENTIALS_FILE": {raw: awsConfigPath}, - }, - Commands: darwinUploadToS3Commands(), - }, - { - Name: "Register artifact", - // Connect's artifact description is automatically generated based on the filename so we pass - // no packageType and extraQualifications. - Commands: tagCreateReleaseAssetCommands(b, "", nil), - Environment: map[string]value{ - "WORKSPACE_DIR": {raw: p.Workspace.Path}, - "RELEASES_CERT": {fromSecret: "RELEASES_CERT"}, - "RELEASES_KEY": {fromSecret: "RELEASES_KEY"}, - }, - }, - cleanUpToolchainsStep(p.Workspace.Path, toolchainConfig), - cleanUpExecStorageStep(p.Workspace.Path), - }..., - ) - return p -} - -func darwinPushPipeline() pipeline { - b := buildType{os: "darwin", arch: "amd64"} - toolchainConfig := toolchainConfig{golang: true, rust: true, nodejs: true} - artifactConfig := binariesWithConnect - - p := newDarwinPipeline("push-build-darwin-amd64") - p.Trigger = trigger{ - Event: triggerRef{Include: []string{"push"}, Exclude: []string{"pull_request"}}, - Branch: triggerRef{Include: []string{"master", "branch/*"}}, - Repo: triggerRef{Include: []string{"gravitational/*"}}, - } - p.Steps = []step{ - setUpExecStorageStep(p.Workspace.Path), - { - Name: "Check out code", - Environment: map[string]value{ - "WORKSPACE_DIR": {raw: p.Workspace.Path}, - "GITHUB_PRIVATE_KEY": {fromSecret: "GITHUB_PRIVATE_KEY"}, - }, - Commands: pushCheckoutCommandsDarwin(artifactConfig), - }, - } - p.Steps = append(p.Steps, - installToolchains(p.Workspace.Path, toolchainConfig)...) - p.Steps = append(p.Steps, []step{ - buildMacArtifactsStep(p.Workspace.Path, b, toolchainConfig, artifactConfig), - cleanUpToolchainsStep(p.Workspace.Path, toolchainConfig), - cleanUpExecStorageStep(p.Workspace.Path), - { - Name: "Send Slack notification (exec)", - Environment: map[string]value{"SLACK_WEBHOOK_DEV_TELEPORT": {fromSecret: "SLACK_WEBHOOK_DEV_TELEPORT"}}, - Commands: []string{ - ` -export DRONE_BUILD_LINK="${DRONE_SYSTEM_PROTO}://${DRONE_SYSTEM_HOSTNAME}/${DRONE_REPO_OWNER}/${DRONE_REPO_NAME}/${DRONE_BUILD_NUMBER}" -export GOOS=$(go env GOOS) -export GOARCH=$(go env GOARCH) -`, - fmt.Sprintf(` -curl -sL -X POST -H 'Content-type: application/json' --data "{\"text\":\"Warning: %s artifact build failed for [%s] - please investigate immediately!\nBranch: %s\nCommit: %s\nLink: $DRONE_BUILD_LINK\"}" $SLACK_WEBHOOK_DEV_TELEPORT`, - escapedPreformatted("${GOOS}-${GOARCH}"), - escapedPreformatted("${DRONE_REPO_NAME}"), - escapedPreformatted("${DRONE_BRANCH}"), - escapedPreformatted("${DRONE_COMMIT_SHA}")), - }, - When: &condition{Status: []string{"failure"}}, - }, - }...) - return p -} - -func darwinTagPipeline() pipeline { - b := buildType{ - arch: "amd64", - os: "darwin", - } - toolchainConfig := toolchainConfig{golang: true, rust: true, nodejs: true} - artifactConfig := onlyBinaries - - p := newDarwinPipeline("build-darwin-amd64") - awsConfigPath := filepath.Join(p.Workspace.Path, "credentials") - p.Trigger = triggerTag - p.DependsOn = []string{tagCleanupPipelineName} - p.Steps = []step{ - setUpExecStorageStep(p.Workspace.Path), - { - Name: "Check out code", - Environment: map[string]value{ - "WORKSPACE_DIR": {raw: p.Workspace.Path}, - "GITHUB_PRIVATE_KEY": {fromSecret: "GITHUB_PRIVATE_KEY"}, - }, - Commands: darwinTagCheckoutCommands(artifactConfig), - }, - } - p.Steps = append(p.Steps, - installToolchains(p.Workspace.Path, toolchainConfig)..., - ) - p.Steps = append(p.Steps, []step{ - buildMacArtifactsStep(p.Workspace.Path, b, toolchainConfig, artifactConfig), - { - Name: "Copy Mac artifacts", - Environment: map[string]value{ - "WORKSPACE_DIR": {raw: p.Workspace.Path}, - }, - Commands: darwinTagCopyPackageArtifactCommands(), - }, - macAssumeAwsRoleStep(macRoleSettings{ - awsRoleSettings: awsRoleSettings{ - awsAccessKeyID: value{fromSecret: "AWS_ACCESS_KEY_ID"}, - awsSecretAccessKey: value{fromSecret: "AWS_SECRET_ACCESS_KEY"}, - role: value{fromSecret: "AWS_ROLE"}, - }, - configPath: awsConfigPath, - }), - { - Name: "Upload to S3", - Environment: map[string]value{ - "AWS_S3_BUCKET": {fromSecret: "AWS_S3_BUCKET"}, - "AWS_REGION": {raw: "us-west-2"}, - "WORKSPACE_DIR": {raw: p.Workspace.Path}, - "AWS_SHARED_CREDENTIALS_FILE": {raw: awsConfigPath}, - }, - Commands: darwinUploadToS3Commands(), - }, - { - Name: "Register artifacts", - // Binaries built by this pipeline don't require extra description, so we don't pass - // packageType and extraQualifications. - Commands: tagCreateReleaseAssetCommands(b, "", nil), - Environment: map[string]value{ - "WORKSPACE_DIR": {raw: p.Workspace.Path}, - "RELEASES_CERT": {fromSecret: "RELEASES_CERT"}, - "RELEASES_KEY": {fromSecret: "RELEASES_KEY"}, - }, - }, - cleanUpToolchainsStep(p.Workspace.Path, toolchainConfig), - cleanUpExecStorageStep(p.Workspace.Path), - }...) - return p -} - -func pushCheckoutCommandsDarwin(artifactConfig darwinArtifactConfig) []string { - commands := []string{ - `set -u`, - `mkdir -p $WORKSPACE_DIR/go/src/github.com/gravitational/teleport`, - `cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport`, - `git clone https://github.com/gravitational/${DRONE_REPO_NAME}.git .`, - `git checkout ${DRONE_TAG:-$DRONE_COMMIT}`, - // suppressing the newline on the end of the private key makes git operations fail on MacOS - // with an error like 'Load key "/path/.ssh/id_rsa": invalid format' - `mkdir -m 0700 $WORKSPACE_DIR/.ssh && echo "$GITHUB_PRIVATE_KEY" > $WORKSPACE_DIR/.ssh/id_rsa && chmod 600 $WORKSPACE_DIR/.ssh/id_rsa`, - `ssh-keyscan -H github.com > $WORKSPACE_DIR/.ssh/known_hosts 2>/dev/null`, - `chmod 600 $WORKSPACE_DIR/.ssh/known_hosts`, - } - - commands = append(commands, - // fetch enterprise submodules - `GIT_SSH_COMMAND='ssh -i $WORKSPACE_DIR/.ssh/id_rsa -o UserKnownHostsFile=$WORKSPACE_DIR/.ssh/known_hosts -F /dev/null' git submodule update --init e`, - `rm -rf $WORKSPACE_DIR/.ssh`, - `mkdir -p $WORKSPACE_DIR/go/cache`, - ) - - return commands -} - -func setUpExecStorageStep(path string) step { - return step{ - Name: "Set up exec runner storage", - Environment: map[string]value{"WORKSPACE_DIR": {raw: path}}, - Commands: []string{ - "set -u", - "mkdir -p $WORKSPACE_DIR", - "chmod -R u+rw $WORKSPACE_DIR", - "rm -rf $WORKSPACE_DIR/go $WORKSPACE_DIR/.ssh", - }, - } -} - -type toolchainConfig struct { - golang bool - rust bool - nodejs bool -} - -func installToolchains(workspacePath string, config toolchainConfig) (steps []step) { - if config.golang { - steps = append(steps, installGoToolchainStep()) - } - - if config.rust { - steps = append(steps, installRustToolchainStep(workspacePath)) - } - - if config.nodejs { - steps = append(steps, installNodeToolchainStep(workspacePath)) - } - - return steps -} - -func installGoToolchainStep() step { - return step{ - Name: "Install Go Toolchain", - Environment: map[string]value{ - "RUNTIME": goRuntime, - }, - Commands: []string{ - `set -u`, - `mkdir -p ` + perBuildToolchainsDir, - `curl --silent -O https://dl.google.com/go/$RUNTIME.darwin-amd64.tar.gz`, - `tar -C ` + perBuildToolchainsDir + ` -xzf $RUNTIME.darwin-amd64.tar.gz`, - `rm -rf $RUNTIME.darwin-amd64.tar.gz`, - }, - } -} - -func installRustToolchainStep(path string) step { - return step{ - Name: "Install Rust Toolchain", - Environment: map[string]value{"WORKSPACE_DIR": {raw: path}}, - Commands: []string{ - `set -u`, - `export PATH=/Users/$(whoami)/.cargo/bin:$PATH`, // use the system-installed rustup to install our custom Rust version - `mkdir -p ` + perBuildToolchainsDir, - `export RUST_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets print-rust-version)`, - `export CARGO_HOME=` + perBuildCargoDir, - `export RUST_HOME=$CARGO_HOME`, - `export RUSTUP_HOME=` + perBuildRustupDir, - `rustup toolchain install $RUST_VERSION`, - }, - } -} - -func installNodeToolchainStep(workspacePath string) step { - return step{ - Name: "Install Node Toolchain", - Environment: map[string]value{"WORKSPACE_DIR": {raw: workspacePath}}, - Commands: []string{ - `set -u`, - `export NODE_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets print-node-version)`, - `export TOOLCHAIN_DIR=` + perBuildToolchainsDir, - `export NODE_DIR=$TOOLCHAIN_DIR/node-v$NODE_VERSION-darwin-x64`, - `mkdir -p $TOOLCHAIN_DIR`, - `curl --silent -O https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-darwin-x64.tar.gz`, - `tar -C $TOOLCHAIN_DIR -xzf node-v$NODE_VERSION-darwin-x64.tar.gz`, - `rm -f node-v$NODE_VERSION-darwin-x64.tar.gz`, - `export PATH=$NODE_DIR/bin:$PATH`, - `corepack enable yarn`, - `echo Node reporting version $(node --version)`, - `echo Yarn reporting version $(yarn --version)`, - }, - } -} - -func configureToolchainsCommands(config toolchainConfig) []string { - commands := []string{ - // HOME needs to be set to the actual home directory of a macOS user rather than the temporary - // directory that Drone sets it to by default. This way we're able to unlock Keychain which is - // needed for Connect signing. - // - // Hence, the toolchains are not installed within the temporary home dir but a separate - // TOOLCHAIN_DIR. Every pipeline in this file follows this pattern even though technically we - // need to unlock Keychain only for the build-darwin-amd64-connect pipeline. - `export HOME=/Users/$(whoami)`, - `export TOOLCHAIN_DIR=` + perBuildToolchainsDir, - `security unlock-keychain -p $${BUILDBOX_PASSWORD} login.keychain`, - `security find-identity -v`, - } - - // Configure toolchains in descending order so that Node.js is added to PATH last. - // We expect that Node.js will add the most packages so we want to avoid any bin conflicts with Go - // or Rust toolchains. - if config.nodejs { - commands = append(commands, - `export NODE_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets print-node-version)`, - `export NODE_HOME=$TOOLCHAIN_DIR/node-v$NODE_VERSION-darwin-x64`, - `export PATH=$NODE_HOME/bin:$PATH`, - ) - } - - if config.rust { - commands = append(commands, - `export RUST_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets print-rust-version)`, - `export CARGO_HOME=`+perBuildCargoDir, - `export RUST_HOME=$CARGO_HOME`, - `export RUSTUP_HOME=`+perBuildRustupDir, - `export PATH=$CARGO_HOME/bin:/Users/build/.cargo/bin:$PATH`, - `rustup override set $RUST_VERSION`, - ) - } - - if config.golang { - commands = append(commands, - `export PATH=$TOOLCHAIN_DIR/go/bin:$PATH`, - ) - } - - return commands -} - -func cleanUpToolchainsStep(workspacePath string, config toolchainConfig) step { - step := step{ - Name: "Clean up toolchains (post)", - Environment: map[string]value{"WORKSPACE_DIR": {raw: workspacePath}}, - When: &condition{ - Status: []string{"success", "failure"}, - }, - Commands: []string{ - `set -u`, - }, - } - - if config.rust { - step.Commands = append(step.Commands, - `export PATH=/Users/$(whoami)/.cargo/bin:$PATH`, - `export CARGO_HOME=`+perBuildCargoDir, - `export RUST_HOME=$CARGO_HOME`, - `export RUSTUP_HOME=`+perBuildRustupDir, - `export RUST_VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build.assets print-rust-version)`, - `cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport`, - // clean up the rust toolchain even though we're about to delete the directory - // this ensures we don't leave behind a broken link - `rustup override unset`, - `rustup toolchain uninstall $RUST_VERSION`, - ) - } - - step.Commands = append(step.Commands, - `rm -rf `+perBuildDir, - ) - - return step -} - -func cleanUpExecStorageStep(path string) step { - return step{ - Name: "Clean up exec runner storage (post)", - Environment: map[string]value{"WORKSPACE_DIR": {raw: path}}, - Commands: []string{ - `set -u`, - `chmod -R u+rw $WORKSPACE_DIR`, - `rm -rf $WORKSPACE_DIR/go $WORKSPACE_DIR/.ssh`, - }, - } -} - -func darwinTagCheckoutCommands(artifactConfig darwinArtifactConfig) []string { - return append( - pushCheckoutCommandsDarwin(artifactConfig), - `mkdir -p $WORKSPACE_DIR/go/artifacts`, - `echo "${DRONE_TAG##v}" > $WORKSPACE_DIR/go/.version.txt`, - `cat $WORKSPACE_DIR/go/.version.txt`, - ) -} - -// darwinArtifactConfig describes artifacts made by the build step in different macOS pipelines. -// -// On a commit push, we run one pipeline that builds artifacts (darwinPushPipeline). It uses -// binariesWithConnect as the artifact config as it only checks if we can still compile/build the -// artifacts after a commit lands in master. -// -// On a version tag push, we run two pipelines from this file that build artifacts. First we run -// darwinTagPipeline with onlyBinaries as the artifact config. It builds, among others, the tsh -// binary which later gets signed, bundled into tsh.app and packaged into a .pkg file. -// -// After that, we run darwinConnectDmgPipeline with onlyConnectWithBundledTshApp as the artifact -// config. darwinConnectDmgPipeline downloads the signed tsh.app bundle and puts it within Connect's -// own bundle. -type darwinArtifactConfig int - -const ( - onlyBinaries darwinArtifactConfig = iota - binariesWithConnect - onlyConnectWithBundledTshApp -) - -func buildMacArtifactsStep(workspacePath string, b buildType, toolchainConfig toolchainConfig, artifactConfig darwinArtifactConfig) step { - step := step{ - Name: "Build Mac artifacts", - Environment: map[string]value{ - "GOPATH": {raw: path.Join(workspacePath, "/go")}, - "GOCACHE": {raw: path.Join(workspacePath, "/go/cache")}, - "OS": {raw: b.os}, - "ARCH": {raw: b.arch}, - "WORKSPACE_DIR": {raw: workspacePath}, - "BUILDBOX_PASSWORD": {fromSecret: "BUILDBOX_PASSWORD"}, - "APPLE_USERNAME": {fromSecret: "APPLE_USERNAME"}, - "APPLE_PASSWORD": {fromSecret: "APPLE_PASSWORD"}, - }, - Commands: darwinBuildCommands(toolchainConfig, artifactConfig), - } - - var artifactDesc string - switch artifactConfig { - case onlyBinaries: - artifactDesc = "binaries" - case binariesWithConnect: - artifactDesc = "binaries and Teleport Connect" - case onlyConnectWithBundledTshApp: - artifactDesc = "Teleport Connect" - } - step.Name = step.Name + " (" + artifactDesc + ")" - - if artifactConfig == onlyConnectWithBundledTshApp { - // These credentials are necessary for the signing and notarization of Teleport Connect, which - // is built in to the Electron tooling. - // The rest of the mac artifacts are signed and notarized with gon in the darwin pkg pipeline. - step.Environment["APPLE_USERNAME"] = value{fromSecret: "APPLE_USERNAME"} - step.Environment["APPLE_PASSWORD"] = value{fromSecret: "APPLE_PASSWORD"} - } - - return step -} - -func darwinBuildCommands(toolchainConfig toolchainConfig, artifactConfig darwinArtifactConfig) []string { - commands := []string{ - `set -u`, - } - commands = append(commands, configureToolchainsCommands(toolchainConfig)...) - - // Commands for building binaries. - if artifactConfig == onlyBinaries || artifactConfig == binariesWithConnect { - commands = append(commands, - `cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport`, - `build.assets/build-fido2-macos.sh build`, - `export PKG_CONFIG_PATH="$(build.assets/build-fido2-macos.sh pkg_config_path)"`, - `make clean release OS=$OS ARCH=$ARCH FIDO2=yes TOUCHID=yes PIV=yes`, - ) - } - - // Commands for building Teleport Connect. - if artifactConfig == binariesWithConnect || artifactConfig == onlyConnectWithBundledTshApp { - commands = append(commands, - `export VERSION=$(make -C $WORKSPACE_DIR/go/src/github.com/gravitational/teleport print-version)`, - // BUILD_NUMBER is used by electron-builder to add an extra fourth integer to CFBundleVersion on macOS. - // This makes the full app version look like this: 9.3.5.12489 - // https://www.electron.build/configuration/configuration.html#Configuration-buildVersion - `export BUILD_NUMBER=$DRONE_BUILD_NUMBER`, - - // Unlock Keychain so that electron-builder can use developer ID cert for signing. - `security unlock-keychain -p $${BUILDBOX_PASSWORD} login.keychain`, - `security find-identity -v`, - // CSC_NAME tells electron-builder which cert to use for signing when there are multiple certs - // available. - // https://www.electron.build/code-signing - `export CSC_NAME=0FFD3E3413AB4C599C53FBB1D8CA690915E33D83`, - ) - - if artifactConfig == binariesWithConnect { - commands = append(commands, - `export CONNECT_TSH_BIN_PATH=$WORKSPACE_DIR/go/src/github.com/gravitational/teleport/build/tsh`, - ) - } - - if artifactConfig == onlyConnectWithBundledTshApp { - commands = append(commands, - // Unpack tsh.pkg. - `cd $WORKSPACE_DIR/go/src/github.com/gravitational`, - `pkgutil --expand-full tsh-$${VERSION}.pkg tsh`, - `export CONNECT_TSH_APP_PATH=$WORKSPACE_DIR/go/src/github.com/gravitational/tsh/Payload/tsh.app`, - ) - } - - commands = append(commands, - // Build and package Connect - `cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport`, - // c.extraMetadata.version overwrites the version property from package.json to $VERSION - // https://www.electron.build/configuration/configuration.html#Configuration-extraMetadata - `yarn install && yarn build-term && yarn package-term -c.extraMetadata.version=$VERSION`, - ) - } - - return commands -} - -func darwinTagCopyPackageArtifactCommands() []string { - commands := []string{ - `set -u`, - `cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport`, - // copy release archives to artifact directory - `cp teleport*.tar.gz $WORKSPACE_DIR/go/artifacts`, - `cp e/teleport-ent*.tar.gz $WORKSPACE_DIR/go/artifacts`, - // generate checksums - `cd $WORKSPACE_DIR/go/artifacts && for FILE in teleport*.tar.gz; do shasum -a 256 $FILE > $FILE.sha256; done && ls -l`, - } - - return commands -} - -func darwinConnectCopyDmgArtifactCommands() []string { - commands := []string{ - `set -u`, - // copy dmg to artifact directory - `cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport/web/packages/teleterm/build/release`, - `cp *.dmg $WORKSPACE_DIR/go/artifacts`, - // generate checksums - `cd $WORKSPACE_DIR/go/artifacts && for FILE in *.dmg; do shasum -a 256 "$FILE" > "$FILE.sha256"; done && ls -l`, - } - - return commands -} - -func darwinUploadToS3Commands() []string { - return []string{ - `set -u`, - `cd $WORKSPACE_DIR/go/artifacts`, - `aws s3 sync . s3://$AWS_S3_BUCKET/teleport/tag/${DRONE_TAG##v}`, - } -} - -func darwinConnectDownloadArtifactCommands() []string { - return []string{ - `set -u`, - `export VERSION=$(cat $WORKSPACE_DIR/go/.version.txt)`, - `export S3_PATH="tag/$${DRONE_TAG##v}/"`, - // Download tsh.pkg. We're going to extract tsh.app from it which is then packaged within the - // Teleport Connect bundle. - `aws s3 cp s3://$AWS_S3_BUCKET/teleport/$${S3_PATH}tsh-$${VERSION}.pkg $WORKSPACE_DIR/go/src/github.com/gravitational/`, - } -} diff --git a/dronegen/mac_gha.go b/dronegen/mac_gha.go new file mode 100644 index 0000000000000..9c886a20491b7 --- /dev/null +++ b/dronegen/mac_gha.go @@ -0,0 +1,65 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import "time" + +// darwinTagPipelineGHA returns a pipeline that kicks off a tagged build of +// the Mac (darwin) release assets on GitHub Actions. The action builds: +// * a tarball of signed teleport binaries (teleport, tsh, tctl, tbot). +// * a package with the Teleport binaries (teleport, tsh, tctl, tbot). +// * a package with the tsh binary. +// * a disk image (dmg) of Teleport Connect containing the signed tsh package. +// These build assets are signed and notarized. +func darwinTagPipelineGHA() pipeline { + bt := ghaBuildType{ + buildType: buildType{os: "darwin", arch: "amd64"}, + trigger: triggerTag, + pipelineName: "build-darwin-amd64", + ghaWorkflow: "release-mac-amd64.yaml", + srcRefVar: "DRONE_TAG", + workflowRef: "${DRONE_TAG}", + timeout: 60 * time.Minute, + slackOnError: true, + inputs: map[string]string{ + "release-artifacts": "true", + "build-packages": "true", + }, + } + return ghaBuildPipeline(bt) +} + +// darwinPushPipelineGHA returns a pipeline that kicks off a push build of the +// teleport binaries and the teleport connect dmg. The binaries are signed and +// notarized even though we do not release these assets. This tests that the +// signing and notarization process continues to work so we don't wait until +// release time to discover breakage. +func darwinPushPipelineGHA() pipeline { + bt := ghaBuildType{ + buildType: buildType{os: "darwin", arch: "amd64"}, + trigger: triggerPush, + pipelineName: "push-build-darwin-amd64", + ghaWorkflow: "release-mac-amd64.yaml", + srcRefVar: "DRONE_COMMIT", + workflowRef: "${DRONE_BRANCH}", + timeout: 60 * time.Minute, + slackOnError: true, + inputs: map[string]string{ + "release-artifacts": "false", + "build-packages": "false", + }, + } + return ghaBuildPipeline(bt) +} diff --git a/dronegen/mac_pkg.go b/dronegen/mac_pkg.go deleted file mode 100644 index 20ed18e3d4d8c..0000000000000 --- a/dronegen/mac_pkg.go +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2021 Gravitational, Inc -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "fmt" - "path/filepath" - "strings" -) - -func darwinPkgPipeline(name, makeTarget string, pkgGlobs []string, extraQualifications []string) pipeline { - b := buildType{ - arch: "amd64", - os: "darwin", - } - artifactConfig := onlyBinaries - - p := newDarwinPipeline(name) - awsConfigPath := filepath.Join(p.Workspace.Path, "credentials") - p.Trigger = triggerTag - p.DependsOn = []string{"build-darwin-amd64"} - p.Steps = []step{ - setUpExecStorageStep(p.Workspace.Path), - { - Name: "Check out code", - Environment: map[string]value{ - "WORKSPACE_DIR": {raw: p.Workspace.Path}, - "GITHUB_PRIVATE_KEY": {fromSecret: "GITHUB_PRIVATE_KEY"}, - }, - Commands: darwinTagCheckoutCommands(artifactConfig), - }, - macAssumeAwsRoleStep(macRoleSettings{ - awsRoleSettings: awsRoleSettings{ - awsAccessKeyID: value{fromSecret: "AWS_ACCESS_KEY_ID"}, - awsSecretAccessKey: value{fromSecret: "AWS_SECRET_ACCESS_KEY"}, - role: value{fromSecret: "AWS_ROLE"}, - }, - configPath: awsConfigPath, - }), - { - Name: "Download built tarball artifacts from S3", - Environment: map[string]value{ - "AWS_REGION": {raw: "us-west-2"}, - "AWS_S3_BUCKET": {fromSecret: "AWS_S3_BUCKET"}, - "AWS_SHARED_CREDENTIALS_FILE": {raw: awsConfigPath}, - "GITHUB_PRIVATE_KEY": {fromSecret: "GITHUB_PRIVATE_KEY"}, - "WORKSPACE_DIR": {raw: p.Workspace.Path}, - }, - Commands: darwinTagDownloadArtifactCommands(), - }, - { - Name: "Build Mac pkg release artifacts", - Environment: map[string]value{ - "WORKSPACE_DIR": {raw: p.Workspace.Path}, - "APPLE_USERNAME": {fromSecret: "APPLE_USERNAME"}, - "APPLE_PASSWORD": {fromSecret: "APPLE_PASSWORD"}, - "BUILDBOX_PASSWORD": {fromSecret: "BUILDBOX_PASSWORD"}, - "OSS_TARBALL_PATH": {raw: filepath.Join(p.Workspace.Path, "go/artifacts")}, - "ENT_TARBALL_PATH": {raw: filepath.Join(p.Workspace.Path, "go/artifacts")}, - "OS": {raw: b.os}, - "ARCH": {raw: b.arch}, - }, - Commands: darwinTagPackageCommands(makeTarget), - }, - { - Name: "Copy Mac pkg artifacts", - Environment: map[string]value{ - "WORKSPACE_DIR": {raw: p.Workspace.Path}, - }, - Commands: darwinTagCopyPkgArtifactCommands(pkgGlobs), - }, - { - Name: "Upload to S3", - Environment: map[string]value{ - "AWS_REGION": {raw: "us-west-2"}, - "AWS_S3_BUCKET": {fromSecret: "AWS_S3_BUCKET"}, - "AWS_SHARED_CREDENTIALS_FILE": {raw: awsConfigPath}, - "WORKSPACE_DIR": {raw: p.Workspace.Path}, - }, - Commands: []string{ - `set -u`, - `cd $WORKSPACE_DIR/go/artifacts`, - `aws s3 sync . s3://$AWS_S3_BUCKET/teleport/tag/${DRONE_TAG##v}`, - }, - }, - { - Name: "Register artifacts", - Commands: tagCreateReleaseAssetCommands(b, ".pkg installer", extraQualifications), - Environment: map[string]value{ - "WORKSPACE_DIR": {raw: p.Workspace.Path}, - "RELEASES_CERT": {fromSecret: "RELEASES_CERT"}, - "RELEASES_KEY": {fromSecret: "RELEASES_KEY"}, - }, - }, - cleanUpExecStorageStep(p.Workspace.Path), - } - - return p -} - -func darwinTeleportPkgPipeline() pipeline { - return darwinPkgPipeline("build-darwin-amd64-pkg", "pkg", []string{"build/teleport*.pkg", "e/build/teleport-ent*.pkg"}, nil) -} - -func darwinTshPkgPipeline() pipeline { - return darwinPkgPipeline("build-darwin-amd64-pkg-tsh", "pkg-tsh", []string{"build/tsh*.pkg"}, []string{"tsh client only"}) -} - -func darwinTagDownloadArtifactCommands() []string { - return []string{ - `set -u`, - `export VERSION=$(cat $WORKSPACE_DIR/go/.version.txt)`, - `export S3_PATH="tag/$${DRONE_TAG##v}/"`, - `aws s3 cp s3://$AWS_S3_BUCKET/teleport/$${S3_PATH}teleport-v$${VERSION}-darwin-amd64-bin.tar.gz $WORKSPACE_DIR/go/artifacts/`, - `aws s3 cp s3://$AWS_S3_BUCKET/teleport/$${S3_PATH}teleport-ent-v$${VERSION}-darwin-amd64-bin.tar.gz $WORKSPACE_DIR/go/artifacts/`, - } -} - -func darwinTagPackageCommands(target string) []string { - return []string{ - `set -u`, - `cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport`, - `export VERSION=$(cat $WORKSPACE_DIR/go/.version.txt)`, - // set HOME explicitly (as Drone overrides it normally) - `export HOME=/Users/build`, - // unlock login keychain - `security unlock-keychain -p $${BUILDBOX_PASSWORD} login.keychain`, - // show available certificates - `security find-identity -v`, - // build pkg, target is `pkg` for teleport, `pkg-tsh` for tsh - fmt.Sprintf(`make %s OS=$OS ARCH=$ARCH`, target), - } -} - -func darwinTagCopyPkgArtifactCommands(pkgGlobs []string) []string { - return []string{ - `set -u`, - `cd $WORKSPACE_DIR/go/src/github.com/gravitational/teleport`, - // delete temporary tarball artifacts so we don't re-upload them in the next stage - `rm -rf $WORKSPACE_DIR/go/artifacts/*.tar.gz`, - // copy release archives to artifact directory - fmt.Sprintf(`cp %s $WORKSPACE_DIR/go/artifacts/`, strings.Join(pkgGlobs, " ")), - // generate checksums (for mac) - `cd $WORKSPACE_DIR/go/artifacts && for FILE in *.pkg; do shasum -a 256 $FILE > $FILE.sha256; done && ls -l`, - } -} diff --git a/dronegen/promote.go b/dronegen/promote.go index 6ce456557c4ae..ff0bc037d1ca3 100644 --- a/dronegen/promote.go +++ b/dronegen/promote.go @@ -14,6 +14,8 @@ package main +import "time" + func promoteBuildPipelines() []pipeline { promotePipelines := make([]pipeline, 0) promotePipelines = append(promotePipelines, promoteBuildOsRepoPipelines()...) @@ -23,6 +25,7 @@ func promoteBuildPipelines() []pipeline { trigger: triggerPromote, pipelineName: "promote-teleport-oci-distroless-images", ghaWorkflow: "promote-teleport-oci-distroless.yml", + timeout: 60 * time.Minute, workflowRef: "${DRONE_TAG}", inputs: map[string]string{ "release-source-tag": "${DRONE_TAG}", diff --git a/dronegen/push.go b/dronegen/push.go index d35cf9da45a1f..c7c5ceda6c9d4 100644 --- a/dronegen/push.go +++ b/dronegen/push.go @@ -14,7 +14,10 @@ package main -import "fmt" +import ( + "fmt" + "time" +) // pushCheckoutCommands builds a list of commands for Drone to check out a git commit on a push build func pushCheckoutCommands(b buildType) []string { @@ -76,6 +79,7 @@ func pushPipelines() []pipeline { trigger: triggerPush, pipelineName: "push-build-linux-arm64", ghaWorkflow: "release-linux-arm64.yml", + timeout: 60 * time.Minute, slackOnError: true, srcRefVar: "DRONE_COMMIT", workflowRef: "${DRONE_BRANCH}", @@ -85,7 +89,7 @@ func pushPipelines() []pipeline { // Only amd64 Windows is supported for now. ps = append(ps, pushPipeline(buildType{os: "windows", arch: "amd64", windowsUnsigned: true})) - ps = append(ps, darwinPushPipeline()) + ps = append(ps, darwinPushPipelineGHA()) ps = append(ps, windowsPushPipeline()) return ps } diff --git a/dronegen/tag.go b/dronegen/tag.go index 251e01e5546c9..af30d1e02863a 100644 --- a/dronegen/tag.go +++ b/dronegen/tag.go @@ -17,6 +17,7 @@ package main import ( "fmt" "strings" + "time" ) const ( @@ -195,6 +196,7 @@ func tagPipelines() []pipeline { ghaWorkflow: "release-linux-arm64.yml", srcRefVar: "DRONE_TAG", workflowRef: "${DRONE_TAG}", + timeout: 60 * time.Minute, dependsOn: []string{tagCleanupPipelineName}, inputs: map[string]string{"upload-artifacts": "true"}, })) @@ -206,6 +208,7 @@ func tagPipelines() []pipeline { ghaWorkflow: "release-teleport-oci-distroless.yml", srcRefVar: "DRONE_TAG", workflowRef: "${DRONE_TAG}", + timeout: 60 * time.Minute, dependsOn: []string{ tagCleanupPipelineName, "build-linux-amd64-deb", @@ -221,7 +224,7 @@ func tagPipelines() []pipeline { ps = append(ps, tagPipeline(buildType{os: "linux", arch: "amd64", centos7: true})) ps = append(ps, tagPipeline(buildType{os: "linux", arch: "amd64", centos7: true, fips: true})) - ps = append(ps, darwinTagPipeline(), darwinTeleportPkgPipeline(), darwinTshPkgPipeline(), darwinConnectDmgPipeline()) + ps = append(ps, darwinTagPipelineGHA()) ps = append(ps, windowsTagPipeline()) ps = append(ps, tagCleanupPipeline()) diff --git a/e b/e index 05ef90f579ba9..cad18841d7b0e 160000 --- a/e +++ b/e @@ -1 +1 @@ -Subproject commit 05ef90f579ba9a64d6c90ca65dd0f9934404053b +Subproject commit cad18841d7b0e339f3be8a39f3c1c8de1bd89395