From 757c7ae24548eac012bd466f5b9a43222e6f2b8e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 05:15:22 +0000 Subject: [PATCH 01/13] Add scheduled Docker dependency updater workflow Agent-Logs-Url: https://github.com/udx/worker/sessions/649d8f42-1f9a-4f3d-b578-82a2cdd553ef Co-authored-by: fqjony <12067297+fqjony@users.noreply.github.com> --- .../workflows/docker-dependency-updater.yml | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 .github/workflows/docker-dependency-updater.yml diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml new file mode 100644 index 00000000..83f220f4 --- /dev/null +++ b/.github/workflows/docker-dependency-updater.yml @@ -0,0 +1,124 @@ +--- +name: Docker Dependency Updater + +on: + schedule: + - cron: "0 5 * * 1" + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +jobs: + update-docker-dependencies: + runs-on: ubuntu-24.04 + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y jq + + - name: Update Docker dependencies + id: update + shell: bash + run: | + set -euo pipefail + + dockerfile="Dockerfile" + + update_arg() { + local arg_name="$1" + local new_value="$2" + sed -i -E "s|^ARG ${arg_name}=.*$|ARG ${arg_name}=${new_value}|" "${dockerfile}" + } + + latest_yq_version="$(curl -fsSL https://api.github.com/repos/mikefarah/yq/releases/latest | jq -r '.tag_name | ltrimstr("v")')" + latest_azure_cli_version="$(curl -fsSL https://pypi.org/pypi/azure-cli/json | jq -r '.info.version')" + latest_pip_version="$(curl -fsSL https://pypi.org/pypi/pip/json | jq -r '.info.version')" + latest_gcloud_version="$(curl -fsSL https://dl.google.com/dl/cloudsdk/channels/rapid/components-2.json | jq -r '.version')" + latest_aws_cli_version="$(curl -fsSL https://api.github.com/repos/aws/aws-cli/tags?per_page=1 | jq -r '.[0].name | ltrimstr("v")')" + + update_arg "YQ_VERSION" "${latest_yq_version}" + update_arg "AZURE_CLI_VERSION" "${latest_azure_cli_version}" + update_arg "PIP_VERSION" "${latest_pip_version}" + update_arg "GCLOUD_VERSION" "${latest_gcloud_version}" + + if grep -q '^ARG AWS_CLI_VERSION=' "${dockerfile}"; then + update_arg "AWS_CLI_VERSION" "${latest_aws_cli_version}" + else + awk -v version="${latest_aws_cli_version}" ' + /^ARG GCLOUD_VERSION=/ { + print $0 + print "ARG AWS_CLI_VERSION=" version + next + } + { print } + ' "${dockerfile}" > "${dockerfile}.tmp" + mv "${dockerfile}.tmp" "${dockerfile}" + fi + + sed -i -E 's|https://awscli.amazonaws.com/awscli-exe-linux-\$\{ARCH\}\.zip|https://awscli.amazonaws.com/awscli-exe-linux-\$\{ARCH\}-\$\{AWS_CLI_VERSION\}\.zip|g' "${dockerfile}" + + mapfile -t apt_packages < <( + awk ' + /apt-get install -y --no-install-recommends/ { in_block=1; next } + in_block && /&&/ { in_block=0 } + in_block { + gsub(/\\/, "", $0) + gsub(/^[[:space:]]+/, "", $0) + if ($0 ~ /^[[:alnum:].:+-]+=/) { + split($0, parts, "=") + print parts[1] + } + } + ' "${dockerfile}" + ) + + if [ "${#apt_packages[@]}" -gt 0 ]; then + apt_versions="$( + docker run --rm ubuntu:25.10 bash -s -- "${apt_packages[@]}" <<'EOF' + set -euo pipefail + apt-get update >/dev/null + for pkg in "$@"; do + version="$(apt-cache madison "${pkg}" | awk 'NR==1 {print $3}')" + if [ -n "${version}" ]; then + printf '%s=%s\n' "${pkg}" "${version}" + fi + done + EOF + )" + + while IFS='=' read -r pkg version; do + [ -z "${pkg}" ] && continue + PKG="${pkg}" VERSION="${version}" perl -0pi -e 's/\Q$ENV{PKG}=\E[^\s\\]+/$ENV{PKG}=$ENV{VERSION}/g' "${dockerfile}" + done <<< "${apt_versions}" + fi + + if git diff --quiet -- "${dockerfile}"; then + echo "changed=false" >> "${GITHUB_OUTPUT}" + else + echo "changed=true" >> "${GITHUB_OUTPUT}" + fi + + - name: Create pull request + if: steps.update.outputs.changed == 'true' + uses: peter-evans/create-pull-request@v7 + with: + commit-message: "chore(deps): update docker dependencies" + title: "chore(deps): update Docker dependencies" + body: | + ## Summary + + Automated update of Docker dependencies in `Dockerfile`, including: + + - Ubuntu apt package version pins + - yq version + - Azure CLI version + - AWS CLI version + - Google Cloud SDK version + - pip version used by Azure CLI virtual environment + branch: automation/docker-dependency-updates + delete-branch: true From 45ced20f18d1b6d9faf73e7d26bc3786fe564daa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 05:15:36 +0000 Subject: [PATCH 02/13] Polish docker dependency updater workflow lint Agent-Logs-Url: https://github.com/udx/worker/sessions/649d8f42-1f9a-4f3d-b578-82a2cdd553ef Co-authored-by: fqjony <12067297+fqjony@users.noreply.github.com> --- .github/workflows/docker-dependency-updater.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml index 83f220f4..0833e4c1 100644 --- a/.github/workflows/docker-dependency-updater.yml +++ b/.github/workflows/docker-dependency-updater.yml @@ -1,7 +1,7 @@ --- name: Docker Dependency Updater -on: +"on": schedule: - cron: "0 5 * * 1" workflow_dispatch: @@ -60,7 +60,9 @@ jobs: mv "${dockerfile}.tmp" "${dockerfile}" fi - sed -i -E 's|https://awscli.amazonaws.com/awscli-exe-linux-\$\{ARCH\}\.zip|https://awscli.amazonaws.com/awscli-exe-linux-\$\{ARCH\}-\$\{AWS_CLI_VERSION\}\.zip|g' "${dockerfile}" + aws_cli_url_pattern='https://awscli.amazonaws.com/awscli-exe-linux-${ARCH}.zip' + aws_cli_versioned_url_pattern='https://awscli.amazonaws.com/awscli-exe-linux-${ARCH}-${AWS_CLI_VERSION}.zip' + sed -i -E "s|${aws_cli_url_pattern}|${aws_cli_versioned_url_pattern}|g" "${dockerfile}" mapfile -t apt_packages < <( awk ' From 1321b131a2f564b6cf28bf0a3ecfd15db50d0b0e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 05:16:14 +0000 Subject: [PATCH 03/13] Harden docker dependency updater version checks Agent-Logs-Url: https://github.com/udx/worker/sessions/649d8f42-1f9a-4f3d-b578-82a2cdd553ef Co-authored-by: fqjony <12067297+fqjony@users.noreply.github.com> --- .../workflows/docker-dependency-updater.yml | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml index 0833e4c1..3847d367 100644 --- a/.github/workflows/docker-dependency-updater.yml +++ b/.github/workflows/docker-dependency-updater.yml @@ -35,11 +35,26 @@ jobs: sed -i -E "s|^ARG ${arg_name}=.*$|ARG ${arg_name}=${new_value}|" "${dockerfile}" } + require_value() { + local value_name="$1" + local value="$2" + if [ -z "${value}" ] || [ "${value}" = "null" ]; then + echo "::error::Unable to determine ${value_name}" + exit 1 + fi + } + latest_yq_version="$(curl -fsSL https://api.github.com/repos/mikefarah/yq/releases/latest | jq -r '.tag_name | ltrimstr("v")')" latest_azure_cli_version="$(curl -fsSL https://pypi.org/pypi/azure-cli/json | jq -r '.info.version')" latest_pip_version="$(curl -fsSL https://pypi.org/pypi/pip/json | jq -r '.info.version')" latest_gcloud_version="$(curl -fsSL https://dl.google.com/dl/cloudsdk/channels/rapid/components-2.json | jq -r '.version')" - latest_aws_cli_version="$(curl -fsSL https://api.github.com/repos/aws/aws-cli/tags?per_page=1 | jq -r '.[0].name | ltrimstr("v")')" + latest_aws_cli_version="$(curl -fsSL https://api.github.com/repos/aws/aws-cli/releases/latest | jq -r '.tag_name | ltrimstr("v")')" + + require_value "YQ_VERSION" "${latest_yq_version}" + require_value "AZURE_CLI_VERSION" "${latest_azure_cli_version}" + require_value "PIP_VERSION" "${latest_pip_version}" + require_value "GCLOUD_VERSION" "${latest_gcloud_version}" + require_value "AWS_CLI_VERSION" "${latest_aws_cli_version}" update_arg "YQ_VERSION" "${latest_yq_version}" update_arg "AZURE_CLI_VERSION" "${latest_azure_cli_version}" @@ -60,8 +75,8 @@ jobs: mv "${dockerfile}.tmp" "${dockerfile}" fi - aws_cli_url_pattern='https://awscli.amazonaws.com/awscli-exe-linux-${ARCH}.zip' - aws_cli_versioned_url_pattern='https://awscli.amazonaws.com/awscli-exe-linux-${ARCH}-${AWS_CLI_VERSION}.zip' + aws_cli_url_pattern='https://awscli.amazonaws.com/awscli-exe-linux-\${ARCH}.zip' + aws_cli_versioned_url_pattern='https://awscli.amazonaws.com/awscli-exe-linux-\${ARCH}-\${AWS_CLI_VERSION}.zip' sed -i -E "s|${aws_cli_url_pattern}|${aws_cli_versioned_url_pattern}|g" "${dockerfile}" mapfile -t apt_packages < <( From f26957ba1380c706d2e640dbe5fc3b722bdf082d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 05:16:43 +0000 Subject: [PATCH 04/13] Fix AWS CLI URL substitution in updater workflow Agent-Logs-Url: https://github.com/udx/worker/sessions/649d8f42-1f9a-4f3d-b578-82a2cdd553ef Co-authored-by: fqjony <12067297+fqjony@users.noreply.github.com> --- .github/workflows/docker-dependency-updater.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml index 3847d367..b487bd05 100644 --- a/.github/workflows/docker-dependency-updater.yml +++ b/.github/workflows/docker-dependency-updater.yml @@ -75,9 +75,9 @@ jobs: mv "${dockerfile}.tmp" "${dockerfile}" fi - aws_cli_url_pattern='https://awscli.amazonaws.com/awscli-exe-linux-\${ARCH}.zip' - aws_cli_versioned_url_pattern='https://awscli.amazonaws.com/awscli-exe-linux-\${ARCH}-\${AWS_CLI_VERSION}.zip' - sed -i -E "s|${aws_cli_url_pattern}|${aws_cli_versioned_url_pattern}|g" "${dockerfile}" + sed -i -E \ + 's|https://awscli.amazonaws.com/awscli-exe-linux-\$\{ARCH\}\.zip|https://awscli.amazonaws.com/awscli-exe-linux-\$\{ARCH\}-\$\{AWS_CLI_VERSION\}\.zip|g' \ + "${dockerfile}" mapfile -t apt_packages < <( awk ' From b7f4081dadb202975622e2d5823075930df4ecb6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 05:17:30 +0000 Subject: [PATCH 05/13] Make AWS CLI update source and pinning safer Agent-Logs-Url: https://github.com/udx/worker/sessions/649d8f42-1f9a-4f3d-b578-82a2cdd553ef Co-authored-by: fqjony <12067297+fqjony@users.noreply.github.com> --- .../workflows/docker-dependency-updater.yml | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml index b487bd05..aeef87e3 100644 --- a/.github/workflows/docker-dependency-updater.yml +++ b/.github/workflows/docker-dependency-updater.yml @@ -48,7 +48,7 @@ jobs: latest_azure_cli_version="$(curl -fsSL https://pypi.org/pypi/azure-cli/json | jq -r '.info.version')" latest_pip_version="$(curl -fsSL https://pypi.org/pypi/pip/json | jq -r '.info.version')" latest_gcloud_version="$(curl -fsSL https://dl.google.com/dl/cloudsdk/channels/rapid/components-2.json | jq -r '.version')" - latest_aws_cli_version="$(curl -fsSL https://api.github.com/repos/aws/aws-cli/releases/latest | jq -r '.tag_name | ltrimstr("v")')" + latest_aws_cli_version="$(curl -fsSL https://raw.githubusercontent.com/aws/aws-cli/v2/CHANGELOG.rst | awk '/^[0-9]+\.[0-9]+\.[0-9]+/ { print $1; exit }')" require_value "YQ_VERSION" "${latest_yq_version}" require_value "AZURE_CLI_VERSION" "${latest_azure_cli_version}" @@ -61,24 +61,32 @@ jobs: update_arg "PIP_VERSION" "${latest_pip_version}" update_arg "GCLOUD_VERSION" "${latest_gcloud_version}" - if grep -q '^ARG AWS_CLI_VERSION=' "${dockerfile}"; then - update_arg "AWS_CLI_VERSION" "${latest_aws_cli_version}" + aws_cli_assets_available=true + curl -fsI "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-${latest_aws_cli_version}.zip" >/dev/null || aws_cli_assets_available=false + curl -fsI "https://awscli.amazonaws.com/awscli-exe-linux-aarch64-${latest_aws_cli_version}.zip" >/dev/null || aws_cli_assets_available=false + + if ${aws_cli_assets_available} || grep -q '\${AWS_CLI_VERSION}' "${dockerfile}"; then + if grep -q '^ARG AWS_CLI_VERSION=' "${dockerfile}"; then + update_arg "AWS_CLI_VERSION" "${latest_aws_cli_version}" + else + awk -v version="${latest_aws_cli_version}" ' + /^ARG GCLOUD_VERSION=/ { + print $0 + print "ARG AWS_CLI_VERSION=" version + next + } + { print } + ' "${dockerfile}" > "${dockerfile}.tmp" + mv "${dockerfile}.tmp" "${dockerfile}" + fi + + sed -i -E \ + 's|https://awscli.amazonaws.com/awscli-exe-linux-\$\{ARCH\}\.zip|https://awscli.amazonaws.com/awscli-exe-linux-\$\{ARCH\}-\$\{AWS_CLI_VERSION\}\.zip|g' \ + "${dockerfile}" else - awk -v version="${latest_aws_cli_version}" ' - /^ARG GCLOUD_VERSION=/ { - print $0 - print "ARG AWS_CLI_VERSION=" version - next - } - { print } - ' "${dockerfile}" > "${dockerfile}.tmp" - mv "${dockerfile}.tmp" "${dockerfile}" + echo "::warning::Skipping AWS CLI URL pinning because versioned AWS CLI assets were not available." fi - sed -i -E \ - 's|https://awscli.amazonaws.com/awscli-exe-linux-\$\{ARCH\}\.zip|https://awscli.amazonaws.com/awscli-exe-linux-\$\{ARCH\}-\$\{AWS_CLI_VERSION\}\.zip|g' \ - "${dockerfile}" - mapfile -t apt_packages < <( awk ' /apt-get install -y --no-install-recommends/ { in_block=1; next } From f5face69352219d7eb02cfa1aace371f48bd7d85 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 05:18:51 +0000 Subject: [PATCH 06/13] Add weekly Docker dependency updater workflow with automated PR creation Agent-Logs-Url: https://github.com/udx/worker/sessions/649d8f42-1f9a-4f3d-b578-82a2cdd553ef Co-authored-by: fqjony <12067297+fqjony@users.noreply.github.com> --- .github/workflows/docker-dependency-updater.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml index aeef87e3..5d98cb2d 100644 --- a/.github/workflows/docker-dependency-updater.yml +++ b/.github/workflows/docker-dependency-updater.yml @@ -61,11 +61,14 @@ jobs: update_arg "PIP_VERSION" "${latest_pip_version}" update_arg "GCLOUD_VERSION" "${latest_gcloud_version}" + dockerfile_uses_aws_cli_arg=false + grep -q '\${AWS_CLI_VERSION}' "${dockerfile}" && dockerfile_uses_aws_cli_arg=true + aws_cli_assets_available=true curl -fsI "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-${latest_aws_cli_version}.zip" >/dev/null || aws_cli_assets_available=false curl -fsI "https://awscli.amazonaws.com/awscli-exe-linux-aarch64-${latest_aws_cli_version}.zip" >/dev/null || aws_cli_assets_available=false - if ${aws_cli_assets_available} || grep -q '\${AWS_CLI_VERSION}' "${dockerfile}"; then + if ${aws_cli_assets_available}; then if grep -q '^ARG AWS_CLI_VERSION=' "${dockerfile}"; then update_arg "AWS_CLI_VERSION" "${latest_aws_cli_version}" else @@ -80,11 +83,13 @@ jobs: mv "${dockerfile}.tmp" "${dockerfile}" fi - sed -i -E \ - 's|https://awscli.amazonaws.com/awscli-exe-linux-\$\{ARCH\}\.zip|https://awscli.amazonaws.com/awscli-exe-linux-\$\{ARCH\}-\$\{AWS_CLI_VERSION\}\.zip|g' \ - "${dockerfile}" + if ! ${dockerfile_uses_aws_cli_arg}; then + sed -i -E \ + 's|https://awscli.amazonaws.com/awscli-exe-linux-\$\{ARCH\}\.zip|https://awscli.amazonaws.com/awscli-exe-linux-\$\{ARCH\}-\$\{AWS_CLI_VERSION\}\.zip|g' \ + "${dockerfile}" + fi else - echo "::warning::Skipping AWS CLI URL pinning because versioned AWS CLI assets were not available." + echo "::warning::Skipping AWS CLI update because versioned AWS CLI assets were not available." fi mapfile -t apt_packages < <( From 1b00eadd116d560a7f001644086863450382fd3a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 05:24:28 +0000 Subject: [PATCH 07/13] Switch dependency updater to cloud-agent aligned apt scope Agent-Logs-Url: https://github.com/udx/worker/sessions/aabddbcd-eaab-47af-a62c-44dbe2dbe4a7 Co-authored-by: fqjony <12067297+fqjony@users.noreply.github.com> --- .github/workflows/copilot-setup-steps.yml | 26 +++++ .../workflows/docker-dependency-updater.yml | 95 +++---------------- 2 files changed, 41 insertions(+), 80 deletions(-) create mode 100644 .github/workflows/copilot-setup-steps.yml diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml new file mode 100644 index 00000000..70427808 --- /dev/null +++ b/.github/workflows/copilot-setup-steps.yml @@ -0,0 +1,26 @@ +--- +name: Copilot Setup Steps + +"on": + workflow_dispatch: + push: + paths: + - .github/workflows/copilot-setup-steps.yml + pull_request: + paths: + - .github/workflows/copilot-setup-steps.yml + +jobs: + copilot-setup-steps: + runs-on: ubuntu-24.04 + permissions: + contents: read + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Install base tooling for cloud agent sessions + run: | + sudo apt-get update + sudo apt-get install -y jq make + python3 -m pip install --user yamllint diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml index 5d98cb2d..26f9240d 100644 --- a/.github/workflows/docker-dependency-updater.yml +++ b/.github/workflows/docker-dependency-updater.yml @@ -1,5 +1,5 @@ --- -name: Docker Dependency Updater +name: Docker APT Dependency Updater "on": schedule: @@ -11,86 +11,21 @@ permissions: pull-requests: write jobs: - update-docker-dependencies: + update-docker-apt-dependencies: runs-on: ubuntu-24.04 steps: - name: Checkout repository uses: actions/checkout@v6 - - name: Install dependencies - run: sudo apt-get update && sudo apt-get install -y jq - - - name: Update Docker dependencies + - name: Update apt package pins in Dockerfile id: update shell: bash run: | set -euo pipefail dockerfile="Dockerfile" - - update_arg() { - local arg_name="$1" - local new_value="$2" - sed -i -E "s|^ARG ${arg_name}=.*$|ARG ${arg_name}=${new_value}|" "${dockerfile}" - } - - require_value() { - local value_name="$1" - local value="$2" - if [ -z "${value}" ] || [ "${value}" = "null" ]; then - echo "::error::Unable to determine ${value_name}" - exit 1 - fi - } - - latest_yq_version="$(curl -fsSL https://api.github.com/repos/mikefarah/yq/releases/latest | jq -r '.tag_name | ltrimstr("v")')" - latest_azure_cli_version="$(curl -fsSL https://pypi.org/pypi/azure-cli/json | jq -r '.info.version')" - latest_pip_version="$(curl -fsSL https://pypi.org/pypi/pip/json | jq -r '.info.version')" - latest_gcloud_version="$(curl -fsSL https://dl.google.com/dl/cloudsdk/channels/rapid/components-2.json | jq -r '.version')" - latest_aws_cli_version="$(curl -fsSL https://raw.githubusercontent.com/aws/aws-cli/v2/CHANGELOG.rst | awk '/^[0-9]+\.[0-9]+\.[0-9]+/ { print $1; exit }')" - - require_value "YQ_VERSION" "${latest_yq_version}" - require_value "AZURE_CLI_VERSION" "${latest_azure_cli_version}" - require_value "PIP_VERSION" "${latest_pip_version}" - require_value "GCLOUD_VERSION" "${latest_gcloud_version}" - require_value "AWS_CLI_VERSION" "${latest_aws_cli_version}" - - update_arg "YQ_VERSION" "${latest_yq_version}" - update_arg "AZURE_CLI_VERSION" "${latest_azure_cli_version}" - update_arg "PIP_VERSION" "${latest_pip_version}" - update_arg "GCLOUD_VERSION" "${latest_gcloud_version}" - - dockerfile_uses_aws_cli_arg=false - grep -q '\${AWS_CLI_VERSION}' "${dockerfile}" && dockerfile_uses_aws_cli_arg=true - - aws_cli_assets_available=true - curl -fsI "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-${latest_aws_cli_version}.zip" >/dev/null || aws_cli_assets_available=false - curl -fsI "https://awscli.amazonaws.com/awscli-exe-linux-aarch64-${latest_aws_cli_version}.zip" >/dev/null || aws_cli_assets_available=false - - if ${aws_cli_assets_available}; then - if grep -q '^ARG AWS_CLI_VERSION=' "${dockerfile}"; then - update_arg "AWS_CLI_VERSION" "${latest_aws_cli_version}" - else - awk -v version="${latest_aws_cli_version}" ' - /^ARG GCLOUD_VERSION=/ { - print $0 - print "ARG AWS_CLI_VERSION=" version - next - } - { print } - ' "${dockerfile}" > "${dockerfile}.tmp" - mv "${dockerfile}.tmp" "${dockerfile}" - fi - - if ! ${dockerfile_uses_aws_cli_arg}; then - sed -i -E \ - 's|https://awscli.amazonaws.com/awscli-exe-linux-\$\{ARCH\}\.zip|https://awscli.amazonaws.com/awscli-exe-linux-\$\{ARCH\}-\$\{AWS_CLI_VERSION\}\.zip|g' \ - "${dockerfile}" - fi - else - echo "::warning::Skipping AWS CLI update because versioned AWS CLI assets were not available." - fi + base_image="$(awk '/^FROM / { print $2; exit }' "${dockerfile}")" mapfile -t apt_packages < <( awk ' @@ -109,7 +44,7 @@ jobs: if [ "${#apt_packages[@]}" -gt 0 ]; then apt_versions="$( - docker run --rm ubuntu:25.10 bash -s -- "${apt_packages[@]}" <<'EOF' + docker run --rm "${base_image}" bash -s -- "${apt_packages[@]}" <<'EOF' set -euo pipefail apt-get update >/dev/null for pkg in "$@"; do @@ -133,22 +68,22 @@ jobs: echo "changed=true" >> "${GITHUB_OUTPUT}" fi + - name: Validate Docker build + if: steps.update.outputs.changed == 'true' + run: docker build --progress=plain -t udx-worker-dependency-update-check . + - name: Create pull request if: steps.update.outputs.changed == 'true' uses: peter-evans/create-pull-request@v7 with: - commit-message: "chore(deps): update docker dependencies" - title: "chore(deps): update Docker dependencies" + commit-message: "chore(deps): update Docker apt package pins" + title: "chore(deps): update Docker apt package pins" body: | ## Summary - Automated update of Docker dependencies in `Dockerfile`, including: + Automated update of Docker apt package version pins in `Dockerfile`. - - Ubuntu apt package version pins - - yq version - - Azure CLI version - - AWS CLI version - - Google Cloud SDK version - - pip version used by Azure CLI virtual environment - branch: automation/docker-dependency-updates + Dependabot remains the primary updater for supported ecosystems (Docker base image and GitHub Actions). + This workflow handles apt package pins, which Dependabot does not update. + branch: automation/docker-apt-dependency-updates delete-branch: true From 46efc1608fdc8421d34193e6f359817fe51f402b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 05:25:07 +0000 Subject: [PATCH 08/13] Address workflow review findings for updater setup Agent-Logs-Url: https://github.com/udx/worker/sessions/aabddbcd-eaab-47af-a62c-44dbe2dbe4a7 Co-authored-by: fqjony <12067297+fqjony@users.noreply.github.com> --- .github/workflows/copilot-setup-steps.yml | 2 +- .github/workflows/docker-dependency-updater.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 70427808..cfc9ff3f 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -23,4 +23,4 @@ jobs: run: | sudo apt-get update sudo apt-get install -y jq make - python3 -m pip install --user yamllint + python3 -m pip install --user yamllint==1.38.0 diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml index 26f9240d..cc5b9c65 100644 --- a/.github/workflows/docker-dependency-updater.yml +++ b/.github/workflows/docker-dependency-updater.yml @@ -25,7 +25,7 @@ jobs: set -euo pipefail dockerfile="Dockerfile" - base_image="$(awk '/^FROM / { print $2; exit }' "${dockerfile}")" + base_image="$(awk '$1 == "FROM" { print $2; exit }' "${dockerfile}")" mapfile -t apt_packages < <( awk ' @@ -34,7 +34,7 @@ jobs: in_block { gsub(/\\/, "", $0) gsub(/^[[:space:]]+/, "", $0) - if ($0 ~ /^[[:alnum:].:+-]+=/) { + if ($0 ~ /^[[:alnum:].+-]+=/) { split($0, parts, "=") print parts[1] } @@ -58,7 +58,7 @@ jobs: while IFS='=' read -r pkg version; do [ -z "${pkg}" ] && continue - PKG="${pkg}" VERSION="${version}" perl -0pi -e 's/\Q$ENV{PKG}=\E[^\s\\]+/$ENV{PKG}=$ENV{VERSION}/g' "${dockerfile}" + PKG="${pkg}" VERSION="${version}" perl -0pi -e 's/\Q$ENV{PKG}=\E[0-9A-Za-z.+:~_-]+/$ENV{PKG}=$ENV{VERSION}/g' "${dockerfile}" done <<< "${apt_versions}" fi From b0939ef7763b9a137ca517442de9f8aa35f765a7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 05:25:41 +0000 Subject: [PATCH 09/13] Refine apt replacement regex and validation tag Agent-Logs-Url: https://github.com/udx/worker/sessions/aabddbcd-eaab-47af-a62c-44dbe2dbe4a7 Co-authored-by: fqjony <12067297+fqjony@users.noreply.github.com> --- .github/workflows/docker-dependency-updater.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml index cc5b9c65..79f500eb 100644 --- a/.github/workflows/docker-dependency-updater.yml +++ b/.github/workflows/docker-dependency-updater.yml @@ -58,7 +58,7 @@ jobs: while IFS='=' read -r pkg version; do [ -z "${pkg}" ] && continue - PKG="${pkg}" VERSION="${version}" perl -0pi -e 's/\Q$ENV{PKG}=\E[0-9A-Za-z.+:~_-]+/$ENV{PKG}=$ENV{VERSION}/g' "${dockerfile}" + PKG="${pkg}" VERSION="${version}" perl -0pi -e 's/\Q$ENV{PKG}=\E[0-9A-Za-z.+~:-]+/$ENV{PKG}=$ENV{VERSION}/g' "${dockerfile}" done <<< "${apt_versions}" fi @@ -70,7 +70,7 @@ jobs: - name: Validate Docker build if: steps.update.outputs.changed == 'true' - run: docker build --progress=plain -t udx-worker-dependency-update-check . + run: docker build --progress=plain -t dependency-update-validation . - name: Create pull request if: steps.update.outputs.changed == 'true' From 9047ff6a209611e62dcd020df9d82145d5337b51 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 05:34:45 +0000 Subject: [PATCH 10/13] Add scheduled Copilot session trigger and dynamic Docker dependency updater Agent-Logs-Url: https://github.com/udx/worker/sessions/f9486bae-2271-40e5-8e4e-2857d070bda2 Co-authored-by: fqjony <12067297+fqjony@users.noreply.github.com> --- .../workflows/copilot-scheduled-session.yml | 52 ++++++++++++ .../workflows/docker-dependency-updater.yml | 80 +++++++++++++++++-- 2 files changed, 124 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/copilot-scheduled-session.yml diff --git a/.github/workflows/copilot-scheduled-session.yml b/.github/workflows/copilot-scheduled-session.yml new file mode 100644 index 00000000..b0e72b60 --- /dev/null +++ b/.github/workflows/copilot-scheduled-session.yml @@ -0,0 +1,52 @@ +--- +name: Scheduled Copilot Session + +"on": + schedule: + - cron: "30 5 * * 1" + workflow_dispatch: + +permissions: + issues: write + contents: read + +jobs: + schedule-copilot-session: + runs-on: ubuntu-24.04 + steps: + - name: Create scheduled Copilot issue + uses: actions/github-script@v8 + with: + script: | + const owner = context.repo.owner; + const repo = context.repo.repo; + const title = "chore: scheduled dependency upgrade session"; + + const existing = await github.rest.issues.listForRepo({ + owner, + repo, + state: "open", + creator: "github-actions[bot]", + per_page: 100 + }); + + const alreadyOpen = existing.data.some((issue) => issue.title === title); + if (alreadyOpen) { + core.info("Scheduled Copilot issue is already open. Skipping."); + return; + } + + await github.rest.issues.create({ + owner, + repo, + title, + body: [ + "@copilot please run a dependency upgrade sweep for this repository.", + "", + "Scope:", + "- Check Dockerfile dependency pins and ARG versions for available updates", + "- Update versions when available", + "- Validate with the repository build/tests", + "- Open or update a PR with the changes" + ].join("\n") + }); diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml index 79f500eb..5b95d03a 100644 --- a/.github/workflows/docker-dependency-updater.yml +++ b/.github/workflows/docker-dependency-updater.yml @@ -1,5 +1,5 @@ --- -name: Docker APT Dependency Updater +name: Docker Dependency Updater "on": schedule: @@ -11,14 +11,14 @@ permissions: pull-requests: write jobs: - update-docker-apt-dependencies: + update-docker-dependencies: runs-on: ubuntu-24.04 steps: - name: Checkout repository uses: actions/checkout@v6 - - name: Update apt package pins in Dockerfile + - name: Update Dockerfile dependency pins id: update shell: bash run: | @@ -26,6 +26,11 @@ jobs: dockerfile="Dockerfile" base_image="$(awk '$1 == "FROM" { print $2; exit }' "${dockerfile}")" + update_arg() { + local arg_name="$1" + local new_value="$2" + sed -i -E "s|^ARG ${arg_name}=.*$|ARG ${arg_name}=${new_value}|" "${dockerfile}" + } mapfile -t apt_packages < <( awk ' @@ -62,6 +67,62 @@ jobs: done <<< "${apt_versions}" fi + while IFS='=' read -r arg_name current_value; do + [ -z "${arg_name}" ] && continue + latest_value="" + + pip_package="$( + awk -v arg="${arg_name}" ' + $0 ~ "==\\$\\{" arg "\\}" { + match($0, /[A-Za-z0-9_.-]+==\$\{[A-Za-z0-9_]+\}/) + if (RSTART > 0) { + token=substr($0, RSTART, RLENGTH) + split(token, parts, "==") + print parts[1] + exit + } + } + ' "${dockerfile}" + )" + if [ -n "${pip_package}" ]; then + latest_value="$( + curl -fsSL "https://pypi.org/pypi/${pip_package}/json" 2>/dev/null \ + | jq -r '.info.version // empty' 2>/dev/null || true + )" + fi + + if [ -z "${latest_value}" ]; then + github_repo="$( + grep -m1 -E "github.com/.+/releases/download/.+\\$\\{${arg_name}\\}" "${dockerfile}" \ + | sed -nE 's#.*github\.com/([^/]+/[^/]+)/releases/download/.*#\1#p' || true + )" + if [ -n "${github_repo}" ]; then + latest_value="$( + curl -fsSL "https://api.github.com/repos/${github_repo}/releases/latest" 2>/dev/null \ + | jq -r '.tag_name // empty | ltrimstr("v")' 2>/dev/null || true + )" + fi + fi + + if [ -z "${latest_value}" ] && grep -q "google-cloud-sdk-\${${arg_name}}" "${dockerfile}"; then + latest_value="$( + curl -fsSL https://dl.google.com/dl/cloudsdk/channels/rapid/components-2.json 2>/dev/null \ + | jq -r '.version // empty' 2>/dev/null || true + )" + fi + + if [ -z "${latest_value}" ] && grep -q "awscli-exe-linux-.*\${${arg_name}}" "${dockerfile}"; then + latest_value="$( + curl -fsSL https://raw.githubusercontent.com/aws/aws-cli/v2/CHANGELOG.rst 2>/dev/null \ + | awk '/^[0-9]+\.[0-9]+\.[0-9]+/ { print $1; exit }' || true + )" + fi + + if [ -n "${latest_value}" ] && [ "${latest_value}" != "${current_value}" ]; then + update_arg "${arg_name}" "${latest_value}" + fi + done < <(awk '/^ARG [A-Z0-9_]+=/ { split($2, kv, "="); print kv[1] "=" kv[2] }' "${dockerfile}") + if git diff --quiet -- "${dockerfile}"; then echo "changed=false" >> "${GITHUB_OUTPUT}" else @@ -76,14 +137,17 @@ jobs: if: steps.update.outputs.changed == 'true' uses: peter-evans/create-pull-request@v7 with: - commit-message: "chore(deps): update Docker apt package pins" - title: "chore(deps): update Docker apt package pins" + commit-message: "chore(deps): update Docker dependency pins" + title: "chore(deps): update Docker dependency pins" body: | ## Summary - Automated update of Docker apt package version pins in `Dockerfile`. + Automated update of Docker dependency pins in `Dockerfile`, including: + + - apt package version pins + - ARG-based tool versions discoverable from Dockerfile usage patterns Dependabot remains the primary updater for supported ecosystems (Docker base image and GitHub Actions). - This workflow handles apt package pins, which Dependabot does not update. - branch: automation/docker-apt-dependency-updates + This workflow handles Dockerfile dependency pins that Dependabot does not update. + branch: automation/docker-dependency-updates delete-branch: true From fe0d80ecf86b2c4fd8b5cbd7240fb4bd50e0206a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 05:35:54 +0000 Subject: [PATCH 11/13] Consolidate scheduled copilot trigger into docker updater workflow Agent-Logs-Url: https://github.com/udx/worker/sessions/f9486bae-2271-40e5-8e4e-2857d070bda2 Co-authored-by: fqjony <12067297+fqjony@users.noreply.github.com> --- .../workflows/copilot-scheduled-session.yml | 52 ------------------- .../workflows/docker-dependency-updater.yml | 49 +++++++++++++++-- 2 files changed, 46 insertions(+), 55 deletions(-) delete mode 100644 .github/workflows/copilot-scheduled-session.yml diff --git a/.github/workflows/copilot-scheduled-session.yml b/.github/workflows/copilot-scheduled-session.yml deleted file mode 100644 index b0e72b60..00000000 --- a/.github/workflows/copilot-scheduled-session.yml +++ /dev/null @@ -1,52 +0,0 @@ ---- -name: Scheduled Copilot Session - -"on": - schedule: - - cron: "30 5 * * 1" - workflow_dispatch: - -permissions: - issues: write - contents: read - -jobs: - schedule-copilot-session: - runs-on: ubuntu-24.04 - steps: - - name: Create scheduled Copilot issue - uses: actions/github-script@v8 - with: - script: | - const owner = context.repo.owner; - const repo = context.repo.repo; - const title = "chore: scheduled dependency upgrade session"; - - const existing = await github.rest.issues.listForRepo({ - owner, - repo, - state: "open", - creator: "github-actions[bot]", - per_page: 100 - }); - - const alreadyOpen = existing.data.some((issue) => issue.title === title); - if (alreadyOpen) { - core.info("Scheduled Copilot issue is already open. Skipping."); - return; - } - - await github.rest.issues.create({ - owner, - repo, - title, - body: [ - "@copilot please run a dependency upgrade sweep for this repository.", - "", - "Scope:", - "- Check Dockerfile dependency pins and ARG versions for available updates", - "- Update versions when available", - "- Validate with the repository build/tests", - "- Open or update a PR with the changes" - ].join("\n") - }); diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml index 5b95d03a..39201bf9 100644 --- a/.github/workflows/docker-dependency-updater.yml +++ b/.github/workflows/docker-dependency-updater.yml @@ -9,9 +9,52 @@ name: Docker Dependency Updater permissions: contents: write pull-requests: write + issues: write jobs: + schedule-copilot-session: + if: github.event_name == 'schedule' + runs-on: ubuntu-24.04 + steps: + - name: Create scheduled Copilot issue + uses: actions/github-script@v8 + with: + script: | + const owner = context.repo.owner; + const repo = context.repo.repo; + const title = "chore: scheduled dependency upgrade session"; + + const existing = await github.rest.issues.listForRepo({ + owner, + repo, + state: "open", + creator: "github-actions[bot]", + per_page: 100 + }); + + const alreadyOpen = existing.data.some((issue) => issue.title === title); + if (alreadyOpen) { + core.info("Scheduled Copilot issue is already open. Skipping."); + return; + } + + await github.rest.issues.create({ + owner, + repo, + title, + body: [ + "@copilot please run this workflow in `workflow_dispatch` mode and apply dynamic dependency upgrades.", + "", + "Scope:", + "- Check Dockerfile dependency pins and ARG versions for available updates", + "- Update versions when available", + "- Validate with the repository build/tests", + "- Open or update a PR with the changes" + ].join("\n") + }); + update-docker-dependencies: + if: github.event_name == 'workflow_dispatch' runs-on: ubuntu-24.04 steps: @@ -93,7 +136,7 @@ jobs: if [ -z "${latest_value}" ]; then github_repo="$( - grep -m1 -E "github.com/.+/releases/download/.+\\$\\{${arg_name}\\}" "${dockerfile}" \ + grep -m1 -E "github\\.com/[^/]+/[^/]+/releases/download/.+\\$\\{${arg_name}\\}" "${dockerfile}" \ | sed -nE 's#.*github\.com/([^/]+/[^/]+)/releases/download/.*#\1#p' || true )" if [ -n "${github_repo}" ]; then @@ -104,14 +147,14 @@ jobs: fi fi - if [ -z "${latest_value}" ] && grep -q "google-cloud-sdk-\${${arg_name}}" "${dockerfile}"; then + if [ -z "${latest_value}" ] && grep -Eq "google-cloud-sdk-(\\$\\{${arg_name}\\}|\\$${arg_name})" "${dockerfile}"; then latest_value="$( curl -fsSL https://dl.google.com/dl/cloudsdk/channels/rapid/components-2.json 2>/dev/null \ | jq -r '.version // empty' 2>/dev/null || true )" fi - if [ -z "${latest_value}" ] && grep -q "awscli-exe-linux-.*\${${arg_name}}" "${dockerfile}"; then + if [ -z "${latest_value}" ] && grep -Eq "awscli-exe-linux-.*(\\$\\{${arg_name}\\}|\\$${arg_name})" "${dockerfile}"; then latest_value="$( curl -fsSL https://raw.githubusercontent.com/aws/aws-cli/v2/CHANGELOG.rst 2>/dev/null \ | awk '/^[0-9]+\.[0-9]+\.[0-9]+/ { print $1; exit }' || true From e067a50def95cb25eadb259a84629c73ffa0feef Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 05:44:45 +0000 Subject: [PATCH 12/13] ci: run docker dependency updater validation on push Agent-Logs-Url: https://github.com/udx/worker/sessions/95c8f493-c524-4556-ba4f-b06e47c9efe9 Co-authored-by: fqjony <12067297+fqjony@users.noreply.github.com> --- .github/workflows/docker-dependency-updater.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml index 39201bf9..b9f8c4ad 100644 --- a/.github/workflows/docker-dependency-updater.yml +++ b/.github/workflows/docker-dependency-updater.yml @@ -4,6 +4,10 @@ name: Docker Dependency Updater "on": schedule: - cron: "0 5 * * 1" + push: + paths: + - Dockerfile + - .github/workflows/docker-dependency-updater.yml workflow_dispatch: permissions: @@ -54,7 +58,7 @@ jobs: }); update-docker-dependencies: - if: github.event_name == 'workflow_dispatch' + if: github.event_name == 'workflow_dispatch' || github.event_name == 'push' runs-on: ubuntu-24.04 steps: @@ -173,11 +177,11 @@ jobs: fi - name: Validate Docker build - if: steps.update.outputs.changed == 'true' + if: github.event_name == 'push' || steps.update.outputs.changed == 'true' run: docker build --progress=plain -t dependency-update-validation . - name: Create pull request - if: steps.update.outputs.changed == 'true' + if: github.event_name == 'workflow_dispatch' && steps.update.outputs.changed == 'true' uses: peter-evans/create-pull-request@v7 with: commit-message: "chore(deps): update Docker dependency pins" From 3a2ac6eab28f23df965c13279713e5090d3c685c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 05:49:10 +0000 Subject: [PATCH 13/13] ci: avoid duplicate docker build in updater push runs Agent-Logs-Url: https://github.com/udx/worker/sessions/c104d67e-557e-4222-88c9-f7e900957048 Co-authored-by: fqjony <12067297+fqjony@users.noreply.github.com> --- .github/workflows/docker-dependency-updater.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-dependency-updater.yml b/.github/workflows/docker-dependency-updater.yml index b9f8c4ad..1ed9d16d 100644 --- a/.github/workflows/docker-dependency-updater.yml +++ b/.github/workflows/docker-dependency-updater.yml @@ -177,7 +177,7 @@ jobs: fi - name: Validate Docker build - if: github.event_name == 'push' || steps.update.outputs.changed == 'true' + if: github.event_name == 'workflow_dispatch' && steps.update.outputs.changed == 'true' run: docker build --progress=plain -t dependency-update-validation . - name: Create pull request