From 76d7dc165e017b6d5c0009c94cdd07ef87ef41be Mon Sep 17 00:00:00 2001 From: Severin Neumann Date: Mon, 22 Jan 2024 20:49:31 +0100 Subject: [PATCH] Add script to auto update registry entries (#3840) Signed-off-by: svrnm Co-authored-by: Phillip Carter --- .github/workflows/auto-update-registry.yml | 30 +++++ .../scripts/update-registry-versions.sh | 121 ++++++++++++++++++ scripts/update-registry-versions.sh | 85 ------------ 3 files changed, 151 insertions(+), 85 deletions(-) create mode 100644 .github/workflows/auto-update-registry.yml create mode 100755 .github/workflows/scripts/update-registry-versions.sh delete mode 100755 scripts/update-registry-versions.sh diff --git a/.github/workflows/auto-update-registry.yml b/.github/workflows/auto-update-registry.yml new file mode 100644 index 000000000000..4245c42a0a5f --- /dev/null +++ b/.github/workflows/auto-update-registry.yml @@ -0,0 +1,30 @@ +name: Auto-update registry versions + +on: + workflow_dispatch: + schedule: + # At 04:31, every day + - cron: 31 4 * * * + +jobs: + auto-update-versions: + name: Auto-update registry versions + runs-on: ubuntu-20.04 + # Remove the if statement below when testing againt a fork + if: github.repository == 'open-telemetry/opentelemetry.io' + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Use CLA approved github bot + run: | + git config user.name opentelemetrybot + git config user.email 107717825+opentelemetrybot@users.noreply.github.com + + - name: Auto-update + run: | + .github/workflows/scripts/update-registry-versions.sh + env: + # change this to secrets.GITHUB_TOKEN when testing against a fork + # GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }} diff --git a/.github/workflows/scripts/update-registry-versions.sh b/.github/workflows/scripts/update-registry-versions.sh new file mode 100755 index 000000000000..72e7deca8591 --- /dev/null +++ b/.github/workflows/scripts/update-registry-versions.sh @@ -0,0 +1,121 @@ +#!/bin/bash -e + +UPDATE_YAML="yq eval -i" +GIT=git +GH=gh +FILES="${FILES:-./data/registry/*.yml}" + + +if [[ -n "$GITHUB_ACTIONS" ]]; then + # Ensure that we're starting from a clean state + git reset --hard origin/main +elif [[ "$1" != "-f" ]]; then + # Do a dry-run when script it executed locally, unless the + # force flag is specified (-f). + echo "Doing a dry-run when run locally. Use -f as the first argument to force execution." + UPDATE_YAML="yq eval" + GIT="echo > DRY RUN: git " + GH="echo > DRY RUN: gh " +else + # Local execution with -f flag (force real vs. dry run) + shift +fi + +body="" + +for yaml_file in ${FILES}; do + echo $yaml_file + # Check if yq is installed + if ! command -v yq &> /dev/null; then + echo "yq could not be found, please install yq." + exit 1 + fi + + # Function to get latest version based on registry + get_latest_version() { + package_name=$1 + registry=$2 + + case $registry in + npm) + curl -s "https://registry.npmjs.org/${package_name}/latest" | jq -r '.version' + ;; + packagist) + curl -s "https://repo.packagist.org/p2/${package_name}.json" | jq -r ".packages.\"${package_name}\"[0].version" + ;; + gems) + curl -s "https://rubygems.org/api/v1/versions/${package_name}/latest.json" | jq -r '.version' + ;; + go) + go list -m --versions "$package_name" | awk '{ if (NF > 1) print $NF ; else print "" }' + ;; + go-collector) + go list -m --versions "$package_name" | awk '{ if (NF > 1) print $NF ; else print "" }' + ;; + nuget) + lower_case_package_name=$(echo "$package_name" | tr '[:upper:]' '[:lower:]') + curl -s "https://api.nuget.org/v3/registration5-gz-semver2/${lower_case_package_name}/index.json" | gunzip | jq -r '.items[0].upper' + ;; + hex) + curl -s "https://hex.pm/api/packages/$package_name" | jq -r '.releases | max_by(.inserted_at) | .version' + ;; + *) + echo "Registry not supported." + ;; + esac + } + + # Read package details + name=$(yq eval '.package.name' "$yaml_file") + registry=$(yq eval '.package.registry' "$yaml_file") + current_version=$(yq eval '.package.version' "$yaml_file") + + if [ -z "$name" ] || [ -z "$registry" ]; then + echo "${yaml_file}: Package name and/or registry are missing in the YAML file." + else + # Get latest version + latest_version=$(get_latest_version "$name" "$registry") + + if [ "$latest_version" == "Registry not supported." ]; then + echo "${yaml_file} ($registry): Registry not supported."; + elif [ -z "$latest_version" ]; then + echo "${yaml_file} ($registry): Could not get latest version from registry." + elif [ -z "$current_version" ]; then + ${UPDATE_YAML} ".package.version = \"$latest_version\"" $yaml_file + row="${yaml_file} ($registry): Version field was missing. Populated with the latest version: $latest_version" + echo "${row}" + body="${body}\n- ${row}" + elif [ "$latest_version" != "$current_version" ]; then + ${UPDATE_YAML} ".package.version = \"$latest_version\"" "$yaml_file" + row="($registry): Updated version from $current_version to $latest_version in $yaml_file" + echo "${yaml_file} ${row}" + body="${body}\n- ${row}" + else + echo "${yaml_file} ($registry): Version is already up to date." + fi + fi +done; + +# We use the sha1 over all version updates to uniquely identify the PR. +tag=$(echo body | sha1sum | awk '{print $1;}') +message="Auto-update registry versions (${tag})" +branch="opentelemetrybot/auto-update-registry-${tag}" + + +existing_pr_count=$(gh pr list --state all --search "in:title $message" | wc -l) +if [ "$existing_pr_count" -gt 0 ]; then + echo "PR(s) already exist for '$message'" + gh pr list --state all --search "\"$message\" in:title" + echo "So we won't create another. Exiting." + exit 0 +fi + +$GIT checkout -b "$branch" +$GIT commit -a -m "$message" +$GIT push --set-upstream origin "$branch" + +body_file=$(mktemp) +echo -en "${body}" >> "${body_file}" + +echo "Submitting auto-update PR '$message'." +$GH pr create --title "$message" --body-file "${body_file}" \ No newline at end of file diff --git a/scripts/update-registry-versions.sh b/scripts/update-registry-versions.sh deleted file mode 100755 index 3dacc555e79e..000000000000 --- a/scripts/update-registry-versions.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/bash - -# To update all files in the registry run -# for i in ../data/registry/*; do ./update-registry-versions.sh "$i"; done - -# Check if a file is provided -if [ "$#" -ne 1 ]; then - echo "Usage: $0 " - exit 1 -fi - -yaml_file=$1 - -# Check if yq is installed -if ! command -v yq &> /dev/null; then - echo "yq could not be found, please install yq." - exit 1 -fi - -# Function to get latest version based on registry -get_latest_version() { - package_name=$1 - registry=$2 - - case $registry in - npm) - curl -s "https://registry.npmjs.org/${package_name}/latest" | jq -r '.version' - ;; - packagist) - curl -s "https://repo.packagist.org/p2/${package_name}.json" | jq -r ".packages.\"${package_name}\"[0].version" - ;; - gems) - curl -s "https://rubygems.org/api/v1/versions/${package_name}/latest.json" | jq -r '.version' - ;; - go) - go list -m --versions "$package_name" | awk '{print $NF}' - ;; - go-collector) - go list -m --versions "$package_name" | awk '{print $NF}' - ;; - nuget) - lower_case_package_name=$(echo "$package_name" | tr '[:upper:]' '[:lower:]') - curl -s "https://api.nuget.org/v3/registration5-gz-semver2/${lower_case_package_name}/index.json" | gunzip | jq -r '.items[0].upper' - ;; - hex) - curl -s "https://hex.pm/api/packages/$package_name" | jq -r '.releases | max_by(.inserted_at) | .version' - ;; - *) - echo "Registry not supported." - ;; - esac -} - -# Read package details -name=$(yq eval '.package.name' "$yaml_file") -registry=$(yq eval '.package.registry' "$yaml_file") -current_version=$(yq eval '.package.version' "$yaml_file") - -if [ -z "$name" ] || [ -z "$registry" ]; then - echo "${yaml_file}: Package name and/or registry are missing in the YAML file." - exit 1 -fi - -# Get latest version -latest_version=$(get_latest_version "$name" "$registry") - -if [ "$latest_version" == "Registry not supported." ]; then - echo "${yaml_file}: Registry not supported."; - exit 0 -fi - -# If version field is missing, populate it with the latest version -if [ -z "$current_version" ]; then - yq eval -i ".package.version = \"$latest_version\"" $yaml_file - echo "${yaml_file}: Version field was missing. Populated with the latest version: $latest_version" - exit 0 -fi - -# Compare and update if necessary -if [ "$latest_version" != "$current_version" ]; then - yq eval -i ".package.version = \"$latest_version\"" "$yaml_file" - echo "${yaml_file}: Updated version from $current_version to $latest_version in $yaml_file" -else - echo "${yaml_file}: Version is already up to date." -fi