diff --git a/.github/chainguard/self.update-smoke-test-latest-versions.create-pr.sts.yaml b/.github/chainguard/self.update-smoke-test-latest-versions.create-pr.sts.yaml new file mode 100644 index 00000000000..fc84cb8d5a4 --- /dev/null +++ b/.github/chainguard/self.update-smoke-test-latest-versions.create-pr.sts.yaml @@ -0,0 +1,13 @@ +issuer: https://token.actions.githubusercontent.com + +subject: repo:DataDog/dd-trace-java:ref:refs/heads/master + +claim_pattern: + event_name: (schedule|workflow_dispatch) + ref: refs/heads/master + ref_protected: "true" + job_workflow_ref: DataDog/dd-trace-java/\.github/workflows/update-smoke-test-latest-versions\.yaml@refs/heads/master + +permissions: + contents: write + pull_requests: write diff --git a/.github/workflows/README.md b/.github/workflows/README.md index c33a4521c4d..338807239d0 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -171,6 +171,14 @@ _Action:_ Create a PR updating the Grade dependencies and their locking files. _Recovery:_ Manually trigger the action again. +### update-smoke-test-latest-versions [🔗](update-smoke-test-latest-versions.yaml) + +_Trigger:_ Every week or manually. + +_Action:_ Create a PR updating the pinned "latest" tool versions (Gradle, Maven, Maven Surefire) used by CI Visibility smoke tests. + +_Recovery:_ Manually trigger the action again. + ### update-jmxfetch-submodule [🔗](update-jmxfetch-submodule.yaml) _Trigger:_ Monthly or manually diff --git a/.github/workflows/update-smoke-test-latest-versions.yaml b/.github/workflows/update-smoke-test-latest-versions.yaml new file mode 100644 index 00000000000..2e73a43038f --- /dev/null +++ b/.github/workflows/update-smoke-test-latest-versions.yaml @@ -0,0 +1,158 @@ +name: Update smoke test latest versions +on: + schedule: + - cron: "0 5 * * 0" + workflow_dispatch: + +jobs: + update-smoke-test-latest-versions: + runs-on: ubuntu-latest + name: Update smoke test latest versions + permissions: + contents: read + id-token: write # Required for OIDC token federation + steps: + - uses: DataDog/dd-octo-sts-action@acaa02eee7e3bb0839e4272dacb37b8f3b58ba80 # v1.0.3 + id: octo-sts + with: + scope: DataDog/dd-trace-java + policy: self.update-smoke-test-latest-versions.create-pr + + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2 + + - name: Define branch name + id: define-branch + run: | + DATE=$(date +'%Y%m%d') + echo "branch=ci/update-smoke-test-latest-versions-${DATE}" >> "$GITHUB_OUTPUT" + + - name: Fetch latest Gradle version + id: gradle + run: | + VERSION=$(curl -sf https://services.gradle.org/versions/current | jq -r '.version') + if [ -z "$VERSION" ] || [ "$VERSION" = "null" ]; then + echo "::error::Failed to fetch latest Gradle version" + exit 1 + fi + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "Latest Gradle version: $VERSION" + + - name: Fetch latest stable Maven version + id: maven + run: | + METADATA=$(curl -sf https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/maven-metadata.xml) + # Get all versions, filter out alpha/beta/rc, take the latest + VERSION=$(echo "$METADATA" \ + | xmllint --xpath '//versions/version/text()' - 2>/dev/null \ + | tr ' ' '\n' \ + | grep -v -E '(alpha|beta|rc)' \ + | sort -V \ + | tail -1) + if [ -z "$VERSION" ]; then + echo "::error::Failed to fetch latest stable Maven version" + exit 1 + fi + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "Latest stable Maven version: $VERSION" + + - name: Fetch latest stable Maven Surefire version + id: surefire + run: | + METADATA=$(curl -sf https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-surefire-plugin/maven-metadata.xml) + # Get all versions, filter out alpha/beta, take the latest + VERSION=$(echo "$METADATA" \ + | xmllint --xpath '//versions/version/text()' - 2>/dev/null \ + | tr ' ' '\n' \ + | grep -v -E '(alpha|beta)' \ + | sort -V \ + | tail -1) + if [ -z "$VERSION" ]; then + echo "::error::Failed to fetch latest stable Maven Surefire version" + exit 1 + fi + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "Latest stable Maven Surefire version: $VERSION" + + - name: Update properties files + env: + GRADLE_VERSION: ${{ steps.gradle.outputs.version }} + MAVEN_VERSION: ${{ steps.maven.outputs.version }} + SUREFIRE_VERSION: ${{ steps.surefire.outputs.version }} + run: | + printf '%s\n' \ + "# Pinned \"latest\" versions for CI Visibility Gradle smoke tests." \ + "# Updated automatically by the update-smoke-test-latest-versions workflow." \ + "gradle.version=${GRADLE_VERSION}" \ + > dd-smoke-tests/gradle/src/test/resources/latest-tool-versions.properties + + printf '%s\n' \ + "# Pinned \"latest\" versions for CI Visibility Maven smoke tests." \ + "# Updated automatically by the update-smoke-test-latest-versions workflow." \ + "maven.version=${MAVEN_VERSION}" \ + "maven-surefire.version=${SUREFIRE_VERSION}" \ + > dd-smoke-tests/maven/src/test/resources/latest-tool-versions.properties + + - name: Check for changes + id: check-changes + run: | + if [[ -z "$(git status -s)" ]]; then + echo "No changes to commit." + echo "has_changes=false" >> "$GITHUB_OUTPUT" + else + echo "has_changes=true" >> "$GITHUB_OUTPUT" + fi + + - name: Configure git + if: steps.check-changes.outputs.has_changes == 'true' + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + - name: Create commit + if: steps.check-changes.outputs.has_changes == 'true' + id: create-commit + run: | + git add dd-smoke-tests/gradle/src/test/resources/latest-tool-versions.properties \ + dd-smoke-tests/maven/src/test/resources/latest-tool-versions.properties + git commit -m "chore: Update smoke test latest tool versions" + echo "commit=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + + - name: Push changes + if: steps.check-changes.outputs.has_changes == 'true' + uses: DataDog/commit-headless@05d7b7ee023e2c7d01c47832d420c2503cd416f3 # action/v2.0.3 + with: + token: "${{ steps.octo-sts.outputs.token }}" + branch: "${{ steps.define-branch.outputs.branch }}" + head-sha: "${{ github.sha }}" + create-branch: true + command: push + commits: "${{ steps.create-commit.outputs.commit }}" + + - name: Create pull request + if: steps.check-changes.outputs.has_changes == 'true' + env: + GH_TOKEN: ${{ steps.octo-sts.outputs.token }} + run: | + gh pr create --title "Update smoke test latest tool versions" \ + --base master \ + --head ${{ steps.define-branch.outputs.branch }} \ + --label "tag: dependencies" \ + --label "tag: no release notes" \ + --body "$(cat <<'EOF' + # What Does This Do + + This PR updates the pinned "latest" tool versions used by CI Visibility smoke tests: + - Gradle: ${{ steps.gradle.outputs.version }} + - Maven: ${{ steps.maven.outputs.version }} + - Maven Surefire: ${{ steps.surefire.outputs.version }} + + # Motivation + + Keep smoke tests running against the latest stable versions of build tools. + + # Contributor Checklist + + - [ ] Verify smoke tests pass with the new versions + EOF + )" diff --git a/dd-smoke-tests/gradle/src/test/groovy/datadog/smoketest/AbstractGradleTest.groovy b/dd-smoke-tests/gradle/src/test/groovy/datadog/smoketest/AbstractGradleTest.groovy index 8e2ba38223a..5328b4bacac 100644 --- a/dd-smoke-tests/gradle/src/test/groovy/datadog/smoketest/AbstractGradleTest.groovy +++ b/dd-smoke-tests/gradle/src/test/groovy/datadog/smoketest/AbstractGradleTest.groovy @@ -1,15 +1,9 @@ package datadog.smoketest -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.ObjectMapper import datadog.environment.JavaVirtualMachine import datadog.trace.civisibility.CiVisibilitySmokeTest import datadog.trace.util.ComparableVersion -import okhttp3.OkHttpClient -import okhttp3.Request -import okhttp3.Response import org.gradle.internal.impldep.org.apache.commons.io.FileUtils -import org.gradle.util.GradleVersion import org.junit.jupiter.api.Assumptions import spock.lang.AutoCleanup import spock.lang.Shared @@ -138,16 +132,12 @@ class AbstractGradleTest extends CiVisibilitySmokeTest { } private static String getLatestGradleVersion() { - OkHttpClient client = new OkHttpClient() - Request request = new Request.Builder().url("https://services.gradle.org/versions/current").build() - try (Response response = client.newCall(request).execute()) { - if (!response.successful) { - return GradleVersion.current().version - } - def responseBody = response.body().string() - ObjectMapper mapper = new ObjectMapper() - JsonNode root = mapper.readTree(responseBody) - return root.get("version").asText() + def properties = new Properties() + def stream = AbstractGradleTest.classLoader.getResourceAsStream("latest-tool-versions.properties") + if (stream == null) { + throw new IllegalStateException("Could not find latest-tool-versions.properties on classpath") } + stream.withCloseable { properties.load(it) } + return properties.getProperty("gradle.version") } } diff --git a/dd-smoke-tests/gradle/src/test/resources/latest-tool-versions.properties b/dd-smoke-tests/gradle/src/test/resources/latest-tool-versions.properties new file mode 100644 index 00000000000..20876c70840 --- /dev/null +++ b/dd-smoke-tests/gradle/src/test/resources/latest-tool-versions.properties @@ -0,0 +1,3 @@ +# Pinned "latest" versions for CI Visibility Gradle smoke tests. +# Updated automatically by the update-smoke-test-latest-versions workflow. +gradle.version=9.4.0 diff --git a/dd-smoke-tests/maven/src/test/groovy/datadog/smoketest/MavenSmokeTest.groovy b/dd-smoke-tests/maven/src/test/groovy/datadog/smoketest/MavenSmokeTest.groovy index c426478b3ac..ded0444c940 100644 --- a/dd-smoke-tests/maven/src/test/groovy/datadog/smoketest/MavenSmokeTest.groovy +++ b/dd-smoke-tests/maven/src/test/groovy/datadog/smoketest/MavenSmokeTest.groovy @@ -5,22 +5,15 @@ import datadog.trace.api.civisibility.CIConstants import datadog.trace.api.config.CiVisibilityConfig import datadog.trace.api.config.GeneralConfig import datadog.trace.civisibility.CiVisibilitySmokeTest -import okhttp3.OkHttpClient -import okhttp3.Request -import okhttp3.Response import org.apache.maven.wrapper.MavenWrapperMain import org.slf4j.Logger import org.slf4j.LoggerFactory -import org.w3c.dom.Document -import org.w3c.dom.NodeList import spock.lang.AutoCleanup import spock.lang.IgnoreIf import spock.lang.Shared import spock.lang.TempDir import spock.util.environment.Jvm -import javax.xml.parsers.DocumentBuilder -import javax.xml.parsers.DocumentBuilderFactory import java.nio.file.FileVisitResult import java.nio.file.Files import java.nio.file.Path @@ -442,70 +435,26 @@ class MavenSmokeTest extends CiVisibilitySmokeTest { } } - private static String getLatestMavenVersion() { - OkHttpClient client = new OkHttpClient() - Request request = new Request.Builder().url("https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/maven-metadata.xml").build() - try (Response response = client.newCall(request).execute()) { - if (response.successful) { - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance() - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder() - Document doc = dBuilder.parse(response.body().byteStream()) - doc.getDocumentElement().normalize() - - NodeList versionList = doc.getElementsByTagName("latest") - if (versionList.getLength() > 0) { - def version = versionList.item(0).getTextContent() - if (!version.contains('alpha') && !version.contains('beta') && !version.contains('rc')) { - LOGGER.info("Will run the 'latest' tests with version ${version}") - return version - } - } - } else { - LOGGER.warn("Could not get latest maven version, response from repo.maven.apache.org is ${response.code()}: ${response.body().string()}") - } - } catch (Exception e) { - LOGGER.warn("Could not get latest maven version", e) + private static Properties loadLatestToolVersions() { + def properties = new Properties() + def stream = MavenSmokeTest.classLoader.getResourceAsStream("latest-tool-versions.properties") + if (stream == null) { + throw new IllegalStateException("Could not find latest-tool-versions.properties on classpath") } - def hardcodedLatestVersion = "4.0.0-beta-3" // latest version that is known to work - LOGGER.info("Will run the 'latest' tests with hard-coded version ${hardcodedLatestVersion}") - return hardcodedLatestVersion + stream.withCloseable { properties.load(it) } + return properties + } + + private static String getLatestMavenVersion() { + def version = loadLatestToolVersions().getProperty("maven.version") + LOGGER.info("Will run the 'latest' tests with Maven version ${version}") + return version } private static String getLatestMavenSurefireVersion() { - OkHttpClient client = new OkHttpClient() - Request request = - new Request.Builder() - .url( - "https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-surefire-plugin/maven-metadata.xml") - .build() - try (Response response = client.newCall(request).execute()) { - if (response.isSuccessful()) { - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance() - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder() - Document doc = dBuilder.parse(response.body().byteStream()) - doc.getDocumentElement().normalize() - - NodeList versionList = doc.getElementsByTagName("latest") - if (versionList.getLength() > 0) { - String version = versionList.item(0).getTextContent() - if (!version.contains("alpha") && !version.contains("beta")) { - LOGGER.info("Will run the 'latest' tests with version " + version) - return version - } - } - } else { - LOGGER.warn( - "Could not get latest Maven Surefire version, response from repo.maven.apache.org is " - + response.code() - + ":" - + response.body().string()) - } - } catch (Exception e) { - LOGGER.warn("Could not get latest Maven Surefire version", e) - } - String hardcodedLatestVersion = "3.5.0" // latest version that is known to work - LOGGER.info("Will run the 'latest' tests with hard-coded version " + hardcodedLatestVersion) - return hardcodedLatestVersion + def version = loadLatestToolVersions().getProperty("maven-surefire.version") + LOGGER.info("Will run the 'latest' tests with Maven Surefire version ${version}") + return version } private static BitSet bits(int ... indices) { diff --git a/dd-smoke-tests/maven/src/test/resources/latest-tool-versions.properties b/dd-smoke-tests/maven/src/test/resources/latest-tool-versions.properties new file mode 100644 index 00000000000..6f556c9480b --- /dev/null +++ b/dd-smoke-tests/maven/src/test/resources/latest-tool-versions.properties @@ -0,0 +1,4 @@ +# Pinned "latest" versions for CI Visibility Maven smoke tests. +# Updated automatically by the update-smoke-test-latest-versions workflow. +maven.version=4.0.0-beta-3 +maven-surefire.version=3.5.5