From f8562f26779e07d65816f5516ece0b8278f7ff94 Mon Sep 17 00:00:00 2001 From: Raphael Philipe Mendes da Silva Date: Tue, 31 Jan 2023 14:04:25 -0800 Subject: [PATCH] Add new process for patch releases (#321) (#323) * Add new process for patch releases --------- Signed-off-by: Raphael Silva Co-authored-by: bryan-aguilar <46550959+bryan-aguilar@users.noreply.github.com> Co-authored-by: Anthony Mirabella --- .github/actions/patch-dependencies/action.yml | 106 ++++++++++++++++++ .github/scripts/patch.sh | 63 +++++++++++ .github/workflows/main-build.yml | 32 +++++- .github/workflows/pr-build.yml | 46 +++++++- .github/workflows/release-build.yml | 9 ++ RELEASING.md | 53 +++------ 6 files changed, 269 insertions(+), 40 deletions(-) create mode 100644 .github/actions/patch-dependencies/action.yml create mode 100755 .github/scripts/patch.sh diff --git a/.github/actions/patch-dependencies/action.yml b/.github/actions/patch-dependencies/action.yml new file mode 100644 index 0000000000..2ad90a0bb2 --- /dev/null +++ b/.github/actions/patch-dependencies/action.yml @@ -0,0 +1,106 @@ +name: "Patch dependencies" +description: | + Patches direct dependencies of this project leveraging maven local to publish the results. + + This workflow supports patching opentelemetry-java and opentelemetry-java-instrumentation repositories by executing + the `patch.sh` script that will try to patch those repositories and after that will optionally test and then publish + the artifacts to maven local. + To add a patch you have to add a file in the `.github/patches/` directory with the name of the repository that must + be patched. + This action assumes that java was set correctly. +inputs: + run_tests: + default: "false" + required: false + description: "If the workflow should run tests of the dependencies. Anything different than false will evaluate to true" + branch: + required: true + description: "The branch where this patches are being applied e.g.: release/v1.21.x" + gpg_private_key: + description: "The gpg key used to sign the artifacts" + required: true + gpg_password: + description: "The gpg key password" + required: true +runs: + using: "composite" + steps: + - name: check patches + run: | + if [[ -f .github/patches/${{ inputs.branch }}/opentelemetry-java.patch ]]; then + echo 'patch_otel_java=true' >> $GITHUB_ENV + fi + if [[ -f .github/patches/${{ inputs.branch }}/opentelemetry-java-instrumentation.patch ]]; then + echo 'patch_otel_java_instrumentation=true' >> $GITHUB_ENV + fi + if [[ -f .github/patches/${{ inputs.branch }}/opentelemetry-java-contrib.patch ]]; then + echo 'patch_otel_java_contrib=true' >> $GITHUB_ENV + fi + shell: bash + + - name: Clone and patch repositories + run: .github/scripts/patch.sh "${{ inputs.branch }}" + if: ${{ env.patch_otel_java == 'true' || + env.patch_otel_java_instrumentation == 'true' || + env.patch_otel_java_contrib == 'true' }} + shell: bash + + - name: Build opentelemetry-java with tests + uses: gradle/gradle-build-action@v2 + if: ${{ env.patch_otel_java == 'true' && inputs.run_tests != 'false' }} + with: + arguments: build publishToMavenLocal + build-root-directory: opentelemetry-java + env: + GPG_PRIVATE_KEY: ${{ inputs.gpg_private_key }} + GPG_PASSWORD: ${{ inputs.gpg_password }} + + - name: Build opentelemetry-java + uses: gradle/gradle-build-action@v2 + if: ${{ env.patch_otel_java == 'true' && inputs.run_tests == 'false' }} + with: + arguments: publishToMavenLocal + build-root-directory: opentelemetry-java + env: + GPG_PRIVATE_KEY: ${{ inputs.gpg_private_key }} + GPG_PASSWORD: ${{ inputs.gpg_password }} + + - name: Build opentelemetry-java-contrib with tests + uses: gradle/gradle-build-action@v2 + if: ${{ env.patch_otel_java_contrib == 'true' && inputs.run_tests != 'false' }} + with: + arguments: build publishToMavenLocal + build-root-directory: opentelemetry-java-contrib + env: + GPG_PRIVATE_KEY: ${{ inputs.gpg_private_key }} + GPG_PASSWORD: ${{ inputs.gpg_password }} + + - name: Build opentelemetry-java-contrib + uses: gradle/gradle-build-action@v2 + if: ${{ env.patch_otel_java_contrib == 'true' && inputs.run_tests == 'false' }} + with: + arguments: publishToMavenLocal + build-root-directory: opentelemetry-java-contrib + env: + GPG_PRIVATE_KEY: ${{ inputs.gpg_private_key }} + GPG_PASSWORD: ${{ inputs.gpg_password }} + + - name: Build opentelemetry-java-instrumentation with tests + uses: gradle/gradle-build-action@v2 + if: ${{ env.patch_otel_java_instrumentation == 'true' && inputs.run_tests != 'false' }} + with: + arguments: check -x spotlessCheck publishToMavenLocal + build-root-directory: opentelemetry-java-instrumentation + env: + GPG_PRIVATE_KEY: ${{ inputs.gpg_private_key }} + GPG_PASSWORD: ${{ inputs.gpg_password }} + + - name: Build opentelemetry java instrumentation + uses: gradle/gradle-build-action@v2 + if: ${{ env.patch_otel_java_instrumentation == 'true' && inputs.run_tests == 'false' }} + with: + arguments: publishToMavenLocal + build-root-directory: opentelemetry-java-instrumentation + env: + GPG_PRIVATE_KEY: ${{ inputs.gpg_private_key }} + GPG_PASSWORD: ${{ inputs.gpg_password }} diff --git a/.github/scripts/patch.sh b/.github/scripts/patch.sh new file mode 100755 index 0000000000..ecbb47fc72 --- /dev/null +++ b/.github/scripts/patch.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# Enable debug mode, fail on any command that fail in this script and fail on unset variables +set -x -e -u + +# This parameter will help find the patches to be applied +BRANCH=$1 + +# .github/patches/$BRANCH/versions.sh should define all the versions of the dependencies that we are going to patch +# This is used so that we can properly clone the upstream repositories. +# This file should define the following variables: +# OTEL_JAVA_VERSION. Tag of the opentelemetry-java repository to use. E.g.: JAVA_OTEL_JAVA_VERSION=v1.21.0 +# OTEL_JAVA_INSTRUMENTATION_VERSION. Tag of the opentelemetry-java-instrumentation repository to use, e.g.: OTEL_JAVA_INSTRUMENTATION_VERSION=v1.21.0 +# OTEL_JAVA_CONTRIB_VERSION. Tag of the opentelemetry-java-contrib repository. E.g.: OTEL_JAVA_CONTRIB_VERSION=v1.21.0 +# This script will fail if a variable that is supposed to exist is referenced. + +if [[ ! -f .github/patches/${BRANCH}/versions ]]; then + echo "No versions file found. Skipping patching" + exit 0 +fi + +source .github/patches/${BRANCH}/versions + +git config --global user.email "adot-patch-workflow@github.com" +git config --global user.name "ADOT Patch workflow" + + +OTEL_JAVA_PATCH=".github/patches/${BRANCH}/opentelemetry-java.patch" +if [[ -f "$OTEL_JAVA_PATCH" ]]; then + git clone https://github.com/open-telemetry/opentelemetry-java.git + cd opentelemetry-java + git checkout ${OTEL_JAVA_VERSION} -b tag-${OTEL_JAVA_VERSION} + patch -p1 < ../${OTEL_JAVA_PATCH} + git commit -a -m "ADOT Patch release" + cd - +else + echo "Skiping patching opentelemetry-java" +fi + + +OTEL_JAVA_CONTRIB_PATCH=".github/patches/${BRANCH}/opentelemetry-java-contrib.patch" +if [[ -f "$OTEL_JAVA_CONTRIB_PATCH" ]]; then + git clone https://github.com/open-telemetry/opentelemetry-java-contrib.git + cd opentelemetry-java-contrib + git checkout ${OTEL_JAVA_CONTRIB_VERSION} -b tag-${OTEL_JAVA_CONTRIB_VERSION} + patch -p1 < "../${OTEL_JAVA_CONTRIB_PATCH}" + git commit -a -m "ADOT Patch release" + cd - +else + echo "Skipping patching opentelemetry-java-contrib" +fi + + +OTEL_JAVA_INSTRUMENTATION_PATCH=".github/patches/${BRANCH}/opentelemetry-java-instrumentation.patch" +if [[ -f "$OTEL_JAVA_INSTRUMENTATION_PATCH" ]]; then + git clone https://github.com/open-telemetry/opentelemetry-java-instrumentation.git + cd opentelemetry-java-instrumentation + git checkout ${OTEL_JAVA_INSTRUMENTATION_VERSION} -b tag-${OTEL_JAVA_INSTRUMENTATION_VERSION} + patch -p1 < "../${OTEL_JAVA_INSTRUMENTATION_PATCH}" + git commit -a -m "ADOT Patch release" + cd - +else + echo "Skipping patching opentelemetry-java-instrumentation" +fi diff --git a/.github/workflows/main-build.yml b/.github/workflows/main-build.yml index 31f710576b..8ddf8715f3 100644 --- a/.github/workflows/main-build.yml +++ b/.github/workflows/main-build.yml @@ -3,7 +3,7 @@ on: push: branches: - main - + - "release/v*" env: AWS_DEFAULT_REGION: us-east-1 @@ -12,15 +12,43 @@ permissions: contents: read jobs: + testpatch: + name: Test patches applied to dependencies + runs-on: ubuntu-latest + if: ${{ startsWith(github.ref_name, 'release/v') }} + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-java@v3 + with: + java-version: 17 + distribution: temurin + - uses: gradle/wrapper-validation-action@v1 + - uses: ./.github/actions/patch-dependencies + with: + run_tests: "true" + branch: ${{ github.ref_name }} + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + gpg_password: ${{ secrets.GPG_PASSPHRASE }} + build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: fetch-depth: 0 - - uses: actions/setup-java@v1 + - uses: actions/setup-java@v3 with: java-version: 17 + distribution: temurin + + - name: Publish patched dependencies to maven local + uses: ./.github/actions/patch-dependencies + if: ${{ startsWith(github.ref_name, 'release/v') }} + with: + branch: ${{ github.ref_name }} + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + gpg_password: ${{ secrets.GPG_PASSPHRASE }} + - uses: gradle/wrapper-validation-action@v1 - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml index 34d6153760..952af30e31 100644 --- a/.github/workflows/pr-build.yml +++ b/.github/workflows/pr-build.yml @@ -3,8 +3,30 @@ on: pull_request: branches: - main + - "release/v*" jobs: + testpatch: + name: Test patches applied to dependencies + runs-on: ubuntu-latest + if: ${{ startsWith(github.event.pull_request.base.ref, 'release/v') }} + steps: + - uses: actions/checkout@v2 + + - uses: actions/setup-java@v3 + with: + java-version: 17 + distribution: temurin + + - uses: gradle/wrapper-validation-action@v1 + + - uses: ./.github/actions/patch-dependencies + with: + run_tests: "true" + branch: ${{ github.event.pull_request.base.ref }} + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + gpg_password: ${{ secrets.GPG_PASSPHRASE }} + build: name: Build on ${{ matrix.os }} runs-on: ${{ matrix.os }} @@ -14,17 +36,37 @@ jobs: - macos-latest - ubuntu-latest - windows-latest + exclude: + # Skip windows on patch workflow because it is not possible to build opentelemetry-java on windows + # when the cache is in a different drive than the source code + # Windows is not working for patch workflows, therefore we disable it here + # https://github.com/square/wire/issues/2188 + # https://github.com/open-telemetry/opentelemetry-java/issues/4560 + - os: ${{ startsWith(github.event.pull_request.base.ref, 'release/v') && 'windows-latest' || '' }} steps: - uses: actions/checkout@v2 - - uses: actions/setup-java@v1 + + - uses: actions/setup-java@v3 with: java-version: 17 + distribution: temurin + - uses: gradle/wrapper-validation-action@v1 + + - name: Publish patched dependencies to maven local + uses: ./.github/actions/patch-dependencies + if: ${{ startsWith(github.event.pull_request.base.ref, 'release/v') }} + with: + branch: ${{ github.event.pull_request.base.ref }} + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + gpg_password: ${{ secrets.GPG_PASSPHRASE }} + - name: Build with Gradle with Integration tests - if: ${{ matrix.os == 'ubuntu-latest' }} uses: gradle/gradle-build-action@v2 + if: ${{ matrix.os == 'ubuntu-latest' }} with: arguments: build integrationTests --stacktrace -PenableCoverage=true -PlocalDocker=true + - name: Build with Gradle uses: gradle/gradle-build-action@v2 if: ${{ matrix.os != 'ubuntu-latest' }} diff --git a/.github/workflows/release-build.yml b/.github/workflows/release-build.yml index 758a472add..d412b5ab42 100644 --- a/.github/workflows/release-build.yml +++ b/.github/workflows/release-build.yml @@ -22,6 +22,15 @@ jobs: with: java-version: 17 - uses: gradle/wrapper-validation-action@v1 + + - name: Publish patched dependencies to maven local + uses: ./.github/actions/patch-dependencies + if: ${{ startsWith(github.ref_name, 'release/v') }} + with: + branch: ${{ github.ref_name }} + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + gpg_password: ${{ secrets.GPG_PASSPHRASE }} + - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 with: diff --git a/RELEASING.md b/RELEASING.md index 48e9160865..f0f7b715b7 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -36,49 +36,30 @@ to view a summary of all commits since last release as a reference. All patch releases should include only bug-fixes, and must avoid adding/modifying the public APIs. -Open the patch release build workflow in your browser [here](https://github.com/aws-observability/aws-otel-java-instrumentation/actions?query=workflow%3A%22Patch+Release+Build%22). +Steps: +1. Create a branch from the release that you want to patch. It should follow the convention `release/v..x`. E.g.: if you want to patch release 1.21.0, the name of the branch should be `release/v1.21.x`. +1. Modify the source code/dependencies. You can only update the patch version of opentelemetry dependencies. +1. Optionally prepare patches that can be applied to opentelemetry-java and opentelemetry-java-instrumentation. More details about this in the following section. +1. Create pull request to merge in the release branch. -You will see a button that says "Run workflow". Press the button, enter the version number you want -to release in the input field for version that pops up and the commits you want to cherrypick for the -patch as a comma-separated list. Then, press "Run workflow". - -If the commits cannot be cleanly applied to the release branch, for example because it has diverged -too much from main, then the workflow will fail before building. In this case, you will need to -prepare the release branch manually. +After the pull request is merged, open the release build workflow in your browser [here](https://github.com/aws-observability/aws-otel-java-instrumentation/actions?query=workflow%3A%22Release+Build%22). -This example will assume patching into release branch `v1.2.x` from a git repository with remotes -named `origin` and `upstream`. +Select the branch and provide the version. -``` -$ git remote -v -origin git@github.com:username/opentelemetry-java.git (fetch) -origin git@github.com:username/opentelemetry-java.git (push) -upstream git@github.com:open-telemetry/opentelemetry-java.git (fetch) -upstream git@github.com:open-telemetry/opentelemetry-java.git (push) -``` +### Patching upstream dependencies -First, checkout the release branch +If you need to patch upstream dependencies, you need: -``` -git fetch upstream v1.2.x -git checkout upstream/v1.2.x -``` - -Apply cherrypicks manually and commit. It is ok to apply multiple cherrypicks in a single commit. -Use a commit message such as "Manual cherrypick for commits commithash1, commithash2". - -After commiting the change, push to your fork's branch. - -``` -git push origin v1.2.x -``` +* Provide patch files for each repository that will need to be patched. These files should be located in `.github/patches/release/v..x` and should be named +using the convention `.patch`. The following repositories are supported: opentelemetry-java, opentelemetry-java-instrumentation and opentelemetry-java-contrib. Provide one patch file per repository. The adot patch version of each upstream dependency should be `-adot` where `version` is the version of the upstream dependency and `number` is the number of this patch that should be incremented from 1 per patch version. -Create a PR to have code review and merge this into upstream's release branch. As this was not -applied automatically, we need to do code review to make sure the manual cherrypick is correct. +* Create a `versions` file in the directory `.github/patches/release/v..x`. This file should contain shell variables with the versions of the tags of the repositories which will receive patches. + This file should define the following variables: + * `OTEL_JAVA_VERSION`. Tag of the opentelemetry-java repository to use. E.g.: `JAVA_OTEL_JAVA_VERSION=v1.21.0` + * `OTEL_JAVA_INSTRUMENTATION_VERSION`. Tag of the opentelemetry-java-instrumentation repository to use, e.g.: `OTEL_JAVA_INSTRUMENTATION_VERSION=v1.21.0` + * `OTEL_JAVA_CONTRIB_VERSION`. Tag of the opentelemetry-java-contrib repository. E.g.: `OTEL_JAVA_CONTRIB_VERSION=v1.21.0` -After it is merged, Run the patch release workflow again, but leave the commits input field blank. -The release will be made with the current state of the release branch, which is what you prepared -above. +During the build, ephemeral artifacts will be generated and stored into maven local and those will be used to build the ADOT Java Agent. ## Release candidates