From 49dbb81d4317dd2fa1f102d0e28b0e0d458fac5f Mon Sep 17 00:00:00 2001 From: yoobinshin Date: Tue, 13 Oct 2026 14:06:24 -0700 Subject: [PATCH 1/2] chore: publish only the Arc chart from the MCR workflow Agent images are now built and published to MCR by a separate pipeline, with tags of the form - (e.g. v0.18.16-1). Drop the image build, arch-specific publish and manifest bundling jobs, leaving the workflow to resolve the already-published tags and package the Arc chart. Tags are resolved from the MCR registry API by selecting the highest revision for a release tag. The chart is checked out at the plain release tag, since the revision suffix has no corresponding git tag. Point the Arc chart at the aks/v2/fleet repository path, where the new pipeline publishes, and add a README covering the publishing flow and the chart values whose behavior does not match their names. Co-Authored-By: Claude Opus 5 --- .github/workflows/build-publish-mcr.yml | 260 ++++++------------------ charts/member-agent-arc/.helmignore | 2 + charts/member-agent-arc/README.md | 52 +++++ charts/member-agent-arc/charts_test.go | 10 +- charts/member-agent-arc/values.yaml | 10 +- 5 files changed, 124 insertions(+), 210 deletions(-) create mode 100644 charts/member-agent-arc/README.md diff --git a/.github/workflows/build-publish-mcr.yml b/.github/workflows/build-publish-mcr.yml index 8ffb5bf82..de6917b81 100644 --- a/.github/workflows/build-publish-mcr.yml +++ b/.github/workflows/build-publish-mcr.yml @@ -1,14 +1,18 @@ -# This Github Action will build and publish images to Azure Container Registry (ACR), from where the published images will be -# automatically pushed to the trusted registry, Microsoft Container Registry (MCR). +# This Github Action packages the ARC member cluster agents Helm chart and publishes it to Azure Container +# Registry (ACR), from where it is automatically pushed to the trusted registry, Microsoft Container Registry (MCR). -# TO-DO (chenyu1): evaluate if we need to hide arch-specific images in ACR. +# The agent images are built and published by a separate pipeline; this workflow only resolves their +# already-published tags. name: Building and Pushing to MCR on: workflow_dispatch: inputs: releaseTag: - description: 'Release tag to publish images, defaults to the latest one' + description: 'Release tag of the Azure/fleet images, defaults to the latest one' + type: string + fleetNetworkingReleaseTag: + description: 'Release tag of the Azure/fleet-networking images, defaults to the latest one' type: string permissions: @@ -17,13 +21,15 @@ permissions: env: # `public` indicates images to MCR will be publicly available, and will be removed in the final MCR images - REGISTRY_REPO: public/aks/fleet ARC_REGISTRY_REPO: public/microsoft.fleetmember + # The MCR registry API omits the `public` prefix that the ACR push path carries. + MCR_FLEET_REPO: aks/v2/fleet jobs: prepare-variables: runs-on: ubuntu-latest outputs: + git_ref: ${{ steps.vars.outputs.git_ref }} release_tag: ${{ steps.vars.outputs.release_tag }} fleet_networking_version: ${{ steps.vars.outputs.fleet_networking_version }} arc_helmchart_version: ${{ steps.vars.outputs.arc_helmchart_version }} @@ -34,69 +40,71 @@ jobs: - name: 'Set output variables' id: vars run: | - # set the image version - RELEASE_TAG=${{ inputs.releaseTag }} - if [ -z "$RELEASE_TAG" ]; then - RELEASE_TAG=$(git describe --tags "$(git rev-list --tags --max-count=1)") - echo "The user input release tag is empty, will use the latest tag $RELEASE_TAG." + set -euo pipefail + + # Images are published to MCR as -; the revision is bumped on every rebuild + # of the same source, so the highest one is current. + resolve_mcr_tag() { + local repo="$1" base="$2" tags revision + tags=$(curl -sf --retry 3 --retry-delay 5 --retry-all-errors --max-time 30 \ + "https://mcr.microsoft.com/v2/${repo}/tags/list" | jq -r '.tags[]?') + if [ -z "$tags" ]; then + echo "Failed to list tags for ${repo}." >&2 + return 1 + fi + revision=$(echo "$tags" | grep -E "^${base}-[0-9]+$" | sed "s/^${base}-//" | sort -n | tail -1) + if [ -z "$revision" ]; then + echo "No published revision of ${base} found in ${repo}; available tags:" >&2 + echo "$tags" >&2 + return 1 + fi + echo "${base}-${revision}" + } + + FLEET_RELEASE_TAG="${{ inputs.releaseTag }}" + if [ -z "$FLEET_RELEASE_TAG" ]; then + FLEET_RELEASE_TAG=$(git describe --tags "$(git rev-list --tags --max-count=1)") + echo "The user input release tag is empty, will use the latest tag $FLEET_RELEASE_TAG." fi + + FLEET_NETWORKING_RELEASE_TAG="${{ inputs.fleetNetworkingReleaseTag }}" + if [ -z "$FLEET_NETWORKING_RELEASE_TAG" ]; then + FLEET_NETWORKING_RELEASE_TAG=$(curl -sf --retry 3 --retry-delay 5 --retry-all-errors --max-time 30 \ + "https://api.github.com/repos/Azure/fleet-networking/tags" | jq -r '.[0].name') + echo "The user input fleet-networking release tag is empty, will use the latest tag $FLEET_NETWORKING_RELEASE_TAG." + fi + + # Member agent, refresh token and CRD installer share a revision, so one lookup tags all three. + RELEASE_TAG=$(resolve_mcr_tag "${{ env.MCR_FLEET_REPO }}/member-agent" "$FLEET_RELEASE_TAG") echo "release_tag=$RELEASE_TAG" >> "$GITHUB_OUTPUT" + echo "Using fleet image tag: $RELEASE_TAG" - # Strip 'v' prefix from RELEASE_TAG for helm chart version - ARC_HELMCHART_VERSION="${RELEASE_TAG#v}" - echo "arc_helmchart_version=$ARC_HELMCHART_VERSION" >> "$GITHUB_OUTPUT" - echo "Using Arc Helm Chart version: $ARC_HELMCHART_VERSION" + # The revision suffix has no matching git tag, so checkout uses the plain release tag. + echo "git_ref=$FLEET_RELEASE_TAG" >> "$GITHUB_OUTPUT" - # Fetch the latest fleet-networking version - # NOTE: The fleet-networking image must be cut and pushed to MCR first before retrieving this version - FLEET_NETWORKING_VERSION="${FLEET_NETWORKING_VERSION:-$(curl "https://api.github.com/repos/Azure/fleet-networking/tags" | jq -r '.[0].name')}" + FLEET_NETWORKING_VERSION=$(resolve_mcr_tag "${{ env.MCR_FLEET_REPO }}/mcs-controller-manager" "$FLEET_NETWORKING_RELEASE_TAG") echo "fleet_networking_version=$FLEET_NETWORKING_VERSION" >> "$GITHUB_OUTPUT" - echo "Using Fleet Networking version: $FLEET_NETWORKING_VERSION" + echo "Using fleet-networking image tag: $FLEET_NETWORKING_VERSION" - # NOTE: As exporting a variable from a secret is not possible, the shared variable registry obtained - # from AZURE_REGISTRY secret is not exported from here. + # Helm chart versions must be valid semver, which disallows the leading 'v'. + ARC_HELMCHART_VERSION="${RELEASE_TAG#v}" + echo "arc_helmchart_version=$ARC_HELMCHART_VERSION" >> "$GITHUB_OUTPUT" + echo "Using Arc Helm Chart version: $ARC_HELMCHART_VERSION" - publish-images-amd64: + publish-arc-helm-chart: runs-on: labels: [self-hosted, "1ES.Pool=1es-aks-fleet-pool-ubuntu"] needs: prepare-variables steps: - uses: actions/checkout@v6 with: - ref: ${{ needs.prepare-variables.outputs.release_tag }} + ref: ${{ needs.prepare-variables.outputs.git_ref }} - name: 'Login the ACR' run: | - az login --identity + az login --identity az acr login -n ${{ secrets.AZURE_REGISTRY }} - - name: Build and publish hub-agent - run: | - make docker-build-hub-agent - env: - HUB_AGENT_IMAGE_VERSION: ${{ needs.prepare-variables.outputs.release_tag }}-amd64 - REGISTRY: ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}} - - name: Build and publish member-agent - run: | - make docker-build-member-agent - env: - MEMBER_AGENT_IMAGE_VERSION: ${{ needs.prepare-variables.outputs.release_tag }}-amd64 - REGISTRY: ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}} - - name: Build and publish refresh-token - run: | - make docker-build-refresh-token - env: - REFRESH_TOKEN_IMAGE_VERSION: ${{ needs.prepare-variables.outputs.release_tag }}-amd64 - REGISTRY: ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}} - - name: Build and publish crd-installer - run: | - make docker-build-crd-installer - env: - CRD_INSTALLER_IMAGE_VERSION: ${{ needs.prepare-variables.outputs.release_tag }}-amd64 - REGISTRY: ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}} - # Build Arc Extension for member clusters - # Arc-connected clusters can join fleets as member clusters through an Arc Extension. - # An Arc Extension is a packaged Helm chart that gets deployed to Arc clusters. - # This step packages both the fleet member agent and networking agents into a single - # Helm chart for Arc deployment, since Arc Extensions require all components to be bundled together. + # Arc Extensions require all components bundled in one chart, hence the member agent and the + # networking agents are packaged together here. - name: Build and publish ARC member cluster agents helm chart run: | make helm-package-arc-member-cluster-agents @@ -108,151 +116,3 @@ jobs: MCS_CONTROLLER_IMAGE_VERSION: ${{ needs.prepare-variables.outputs.fleet_networking_version }} MEMBER_NET_CONTROLLER_IMAGE_VERSION: ${{ needs.prepare-variables.outputs.fleet_networking_version }} REGISTRY: ${{ secrets.AZURE_REGISTRY }}/${{ env.ARC_REGISTRY_REPO}} - - publish-images-arm64: - runs-on: - labels: [self-hosted, "1ES.Pool=1es-aks-fleet-pool-ubuntu-arm64"] - needs: prepare-variables - steps: - - uses: actions/checkout@v6 - with: - ref: ${{ needs.prepare-variables.outputs.release_tag }} - - name: 'Install the Azure CLI' - # Note (chenyu1): the self-hosted 1ES ARM64 pool, for some reason, does not have Azure CLI installed by default; - # install it manually here. - run: - curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash - - name: 'Set up build dependencies' - # Note (chenyu1): the self-hosted 1ES ARM64 pool, for some reason, does not have the common build - # tools (e.g., make) installed by default; install them manually. - run: | - sudo apt-get update - sudo apt-get install -y build-essential acl - - name: 'Set up Docker' - # Note (chenyu1): the self-hosted 1ES ARM64 pool, for some reason, does not have Docker installed by default, - # and cannot have Docker installed via the docker/setup-docker-action Github Action, hence the manual setup - # steps here. - run: | - sudo apt-get update - sudo apt-get -y install ca-certificates curl - sudo install -m 0755 -d /etc/apt/keyrings - sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc - sudo chmod a+r /etc/apt/keyrings/docker.asc - echo \ - "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ - $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \ - sudo tee /etc/apt/sources.list.d/docker.list > /dev/null - sudo apt-get update - sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin - - name: 'Enable Docker access' - # Note (chenyu1): there are situations where the newgrp command will not take effect; set access - # to the docker daemon directly just in case. - run: | - sudo groupadd docker || true - echo "Adding $USER to the docker group" - sudo usermod -aG docker "$USER" - newgrp docker - sudo setfacl --modify "user:$USER:rw" /var/run/docker.sock - - name: 'Login the ACR' - # Note (chenyu1): must not use root privileges; the system seems to have some trouble - # retrieving credentials when sudo is used. - run: | - az login --identity - az acr login -n ${{ secrets.AZURE_REGISTRY }} - - name: 'Verify Docker CLI' - run: | - docker version - docker info - - name: Build and publish hub-agent - run: | - make docker-build-hub-agent - env: - HUB_AGENT_IMAGE_VERSION: ${{ needs.prepare-variables.outputs.release_tag }}-arm64 - REGISTRY: ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}} - TARGET_ARCH: arm64 - - name: Build and publish member-agent - run: | - make docker-build-member-agent - env: - MEMBER_AGENT_IMAGE_VERSION: ${{ needs.prepare-variables.outputs.release_tag }}-arm64 - REGISTRY: ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}} - TARGET_ARCH: arm64 - - name: Build and publish refresh-token - run: | - make docker-build-refresh-token - env: - REFRESH_TOKEN_IMAGE_VERSION: ${{ needs.prepare-variables.outputs.release_tag }}-arm64 - REGISTRY: ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}} - TARGET_ARCH: arm64 - - name: Build and publish crd-installer - run: | - make docker-build-crd-installer - env: - CRD_INSTALLER_IMAGE_VERSION: ${{ needs.prepare-variables.outputs.release_tag }}-arm64 - REGISTRY: ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}} - TARGET_ARCH: arm64 - - create-image-manifest-bundle: - runs-on: - # Use the x86_64 1ES pool to run this job; in theory it can be run on the ARM64 1ES pool as well. - labels: [self-hosted, "1ES.Pool=1es-aks-fleet-pool-ubuntu"] - needs: [prepare-variables, publish-images-amd64, publish-images-arm64] - steps: - - name: 'Wait until images are processed' - # Note (chenyu1): as we are pulling from ACR rather than MCR, the images should be available almost - # immediately after the push is done; the delay is added here as a precaution. - run: | - echo "Waiting for 3 minutes to ensure that images are fully processed" - sleep 180 - - name: 'Login the ACR' - run: | - az login --identity - az acr login -n ${{ secrets.AZURE_REGISTRY }} - - name: 'Pull the hub agent images from ACR' - # Note (chenyu1): must set the target platform explictly. - run: | - docker pull --platform linux/amd64 ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/hub-agent:${{ needs.prepare-variables.outputs.release_tag }}-amd64 - docker pull --platform linux/arm64 ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/hub-agent:${{ needs.prepare-variables.outputs.release_tag }}-arm64 - - name: 'Create and push multi-arch image manifests for the hub agent image' - # Note (chenyu1): use `docker buildx imagetools create`, otherwise attestations cannot be perserved. - run: | - docker buildx imagetools create \ - -t ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/hub-agent:${{ needs.prepare-variables.outputs.release_tag }} \ - ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/hub-agent:${{ needs.prepare-variables.outputs.release_tag }}-amd64 \ - ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/hub-agent:${{ needs.prepare-variables.outputs.release_tag }}-arm64 - - name: 'Pull the member agent images from ACR' - # Note (chenyu1): must set the target platform explictly. - run: | - docker pull --platform linux/amd64 ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/member-agent:${{ needs.prepare-variables.outputs.release_tag }}-amd64 - docker pull --platform linux/arm64 ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/member-agent:${{ needs.prepare-variables.outputs.release_tag }}-arm64 - - name: 'Create and push multi-arch image manifests for the member agent image' - # Note (chenyu1): use `docker buildx imagetools create`, otherwise attestations cannot be perserved. - run: | - docker buildx imagetools create \ - -t ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/member-agent:${{ needs.prepare-variables.outputs.release_tag }} \ - ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/member-agent:${{ needs.prepare-variables.outputs.release_tag }}-amd64 \ - ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/member-agent:${{ needs.prepare-variables.outputs.release_tag }}-arm64 - - name: 'Pull the refresh token images from ACR' - # Note (chenyu1): must set the target platform explictly. - run: | - docker pull --platform linux/amd64 ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/refresh-token:${{ needs.prepare-variables.outputs.release_tag }}-amd64 - docker pull --platform linux/arm64 ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/refresh-token:${{ needs.prepare-variables.outputs.release_tag }}-arm64 - - name: 'Create and push multi-arch image manifests for the refresh token image' - # Note (chenyu1): use `docker buildx imagetools create`, otherwise attestations cannot be perserved. - run: | - docker buildx imagetools create \ - -t ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/refresh-token:${{ needs.prepare-variables.outputs.release_tag }} \ - ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/refresh-token:${{ needs.prepare-variables.outputs.release_tag }}-amd64 \ - ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/refresh-token:${{ needs.prepare-variables.outputs.release_tag }}-arm64 - - name: 'Pull the crd installer images from ACR' - # Note (chenyu1): must set the target platform explictly. - run: | - docker pull --platform linux/amd64 ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/crd-installer:${{ needs.prepare-variables.outputs.release_tag }}-amd64 - docker pull --platform linux/arm64 ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/crd-installer:${{ needs.prepare-variables.outputs.release_tag }}-arm64 - - name: 'Create and push multi-arch image manifests for the crd installer image' - # Note (chenyu1): use `docker buildx imagetools create`, otherwise attestations cannot be perserved. - run: | - docker buildx imagetools create \ - -t ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/crd-installer:${{ needs.prepare-variables.outputs.release_tag }} \ - ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/crd-installer:${{ needs.prepare-variables.outputs.release_tag }}-amd64 \ - ${{ secrets.AZURE_REGISTRY }}/${{ env.REGISTRY_REPO}}/crd-installer:${{ needs.prepare-variables.outputs.release_tag }}-arm64 diff --git a/charts/member-agent-arc/.helmignore b/charts/member-agent-arc/.helmignore index 0e8a0eb36..b67ded2ff 100644 --- a/charts/member-agent-arc/.helmignore +++ b/charts/member-agent-arc/.helmignore @@ -21,3 +21,5 @@ .idea/ *.tmproj .vscode/ +# Tests +*_test.go diff --git a/charts/member-agent-arc/README.md b/charts/member-agent-arc/README.md new file mode 100644 index 000000000..a4863168f --- /dev/null +++ b/charts/member-agent-arc/README.md @@ -0,0 +1,52 @@ +# Arc Member Cluster Agents Helm Chart + +Packages the Fleet member agent and the Fleet networking agents as a single Helm chart for deployment to +[Azure Arc-enabled Kubernetes](https://learn.microsoft.com/azure/azure-arc/kubernetes/overview) clusters, allowing +an Arc-connected cluster to join a fleet as a member cluster. + +This chart is consumed as an Arc cluster extension, not installed directly with `helm install`. Arc Extensions +require every component to ship in one chart, which is why the member agent and the networking agents are bundled +here rather than published separately. + +See `values.yaml` for the full set of parameters. This file covers only what that file does not show. + +## Contents + +Three Deployments, all in the hardcoded `fleet-system` namespace: `fleet-member-agent`, +`fleet-mcs-controller-manager`, and `fleet-member-net-controller-manager`. Each also runs an `addon-token-adapter` +and a `refresh-token` container to obtain hub credentials. + +`crdinstaller.enabled` adds a `crd-installer` **init** container to `fleet-member-agent` — it runs to completion +before the agent starts, rather than alongside it. + +## Publishing + +The chart is built and pushed by the `build-publish-mcr` GitHub workflow. Agent images are built and published to +MCR by a separate pipeline; the workflow only resolves their already-published tags. + +Images are published to MCR as `-` (for example `v0.18.16-1`), where the revision is bumped +on every rebuild of the same source. The workflow selects the highest revision and derives the chart version from +it by stripping the leading `v`, so image tag `v0.18.16-1` produces chart version `0.18.16-1`. + +The image tags in `values.yaml` are placeholders of the form `${MEMBER_AGENT_IMAGE_VERSION}`, substituted by +`envsubst` during `make helm-package-arc-member-cluster-agents`. That target rewrites `values.yaml` in place, so +after running it locally restore the file with `git checkout charts/member-agent-arc/values.yaml`. + +## Values that do not behave as their names suggest + +| Parameter | Actual behavior | +|:---|:---| +| `namespace` | Not consumed by any template; all namespaces are hardcoded to `fleet-system`. Setting it has no effect. | +| `Azure.proxySettings.httpsProxy` | Not consumed by any template. Setting it has no effect. | +| `Azure.proxySettings.httpProxy` | Sets the `HTTPS_PROXY` environment variable, not `HTTP_PROXY`. | +| `Azure.proxySettings.proxyCert` | Mounted and used as `SSL_CERT_FILE` only when `isProxyEnabled` is also set. | +| `Azure.proxySettings.isCustomCert` | Absent from `values.yaml`; mounts the proxy certificate for the MCS controller without enabling the proxy. | +| `propertyProvider` | Absent from `values.yaml`; the member agent runs with no property provider when empty. | + +## Testing + +`charts_test.go` renders each template with a maximal set of values to confirm the output is valid YAML: + +```console +go test ./charts/member-agent-arc/... +``` diff --git a/charts/member-agent-arc/charts_test.go b/charts/member-agent-arc/charts_test.go index 29d0e5fa9..96eef095d 100644 --- a/charts/member-agent-arc/charts_test.go +++ b/charts/member-agent-arc/charts_test.go @@ -19,24 +19,24 @@ func TestHelmChartTemplatesRenderValidYAML(t *testing.T) { // Maximal configuration to activate all conditional template paths values := map[string]interface{}{ "memberagent": map[string]interface{}{ - "repository": "mcr.microsoft.com/aks/fleet/member-agent", + "repository": "mcr.microsoft.com/aks/v2/fleet/member-agent", "tag": "v1.0.0", }, "mcscontrollermanager": map[string]interface{}{ - "repository": "mcr.microsoft.com/aks/fleet/mcs-controller-manager", + "repository": "mcr.microsoft.com/aks/v2/fleet/mcs-controller-manager", "tag": "v1.0.0", }, "membernetcontrollermanager": map[string]interface{}{ - "repository": "mcr.microsoft.com/aks/fleet/member-net-controller-manager", + "repository": "mcr.microsoft.com/aks/v2/fleet/member-net-controller-manager", "tag": "v1.0.0", }, "refreshtoken": map[string]interface{}{ - "repository": "mcr.microsoft.com/aks/fleet/refresh-token", + "repository": "mcr.microsoft.com/aks/v2/fleet/refresh-token", "tag": "v1.0.0", }, "crdinstaller": map[string]interface{}{ "enabled": true, - "repository": "mcr.microsoft.com/aks/fleet/crd-installer", + "repository": "mcr.microsoft.com/aks/v2/fleet/crd-installer", "tag": "v1.0.0", "logVerbosity": 2, }, diff --git a/charts/member-agent-arc/values.yaml b/charts/member-agent-arc/values.yaml index c4771c980..b7a1927d8 100644 --- a/charts/member-agent-arc/values.yaml +++ b/charts/member-agent-arc/values.yaml @@ -1,22 +1,22 @@ memberagent: - repository: mcr.microsoft.com/aks/fleet/member-agent + repository: mcr.microsoft.com/aks/v2/fleet/member-agent tag: "${MEMBER_AGENT_IMAGE_VERSION}" mcscontrollermanager: - repository: mcr.microsoft.com/aks/fleet/mcs-controller-manager + repository: mcr.microsoft.com/aks/v2/fleet/mcs-controller-manager tag: "${MCS_CONTROLLER_IMAGE_VERSION}" membernetcontrollermanager: - repository: mcr.microsoft.com/aks/fleet/member-net-controller-manager + repository: mcr.microsoft.com/aks/v2/fleet/member-net-controller-manager tag: "${MEMBER_NET_CONTROLLER_IMAGE_VERSION}" refreshtoken: - repository: mcr.microsoft.com/aks/fleet/refresh-token + repository: mcr.microsoft.com/aks/v2/fleet/refresh-token tag: "${REFRESH_TOKEN_IMAGE_VERSION}" crdinstaller: enabled: true - repository: mcr.microsoft.com/aks/fleet/crd-installer + repository: mcr.microsoft.com/aks/v2/fleet/crd-installer tag: "${CRD_INSTALLER_IMAGE_VERSION}" logVerbosity: 2 From ffab68324f1a3ca29747198806af332af7e60b4f Mon Sep 17 00:00:00 2001 From: yoobinshin Date: Tue, 13 Oct 2026 14:24:07 -0700 Subject: [PATCH 2/2] fix: resolve release tags from the upstream repo, not the checkout git describe reads tags from the checked-out repository, which a fork does not have: GitHub does not copy tags when forking, so the workflow failed with "fatal: No names found, cannot describe anything" on any fork. Read both release tags from the GitHub API instead, matching how the fleet-networking tag was already resolved, and fail with a clear message when a tag cannot be resolved rather than passing "null" downstream. The prepare-variables job no longer needs a checkout. Co-Authored-By: Claude Opus 5 --- .github/workflows/build-publish-mcr.yml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-publish-mcr.yml b/.github/workflows/build-publish-mcr.yml index de6917b81..552fa8c6e 100644 --- a/.github/workflows/build-publish-mcr.yml +++ b/.github/workflows/build-publish-mcr.yml @@ -34,9 +34,6 @@ jobs: fleet_networking_version: ${{ steps.vars.outputs.fleet_networking_version }} arc_helmchart_version: ${{ steps.vars.outputs.arc_helmchart_version }} steps: - - uses: actions/checkout@v6 - with: - fetch-depth: 0 - name: 'Set output variables' id: vars run: | @@ -61,16 +58,28 @@ jobs: echo "${base}-${revision}" } + # Release tags are read from the upstream repositories rather than the checkout, which on a fork + # carries no tags. + latest_github_tag() { + local repo="$1" tag + tag=$(curl -sf --retry 3 --retry-delay 5 --retry-all-errors --max-time 30 \ + "https://api.github.com/repos/${repo}/tags" | jq -r '.[0].name // empty') + if [ -z "$tag" ]; then + echo "Failed to resolve the latest tag of ${repo}." >&2 + return 1 + fi + echo "$tag" + } + FLEET_RELEASE_TAG="${{ inputs.releaseTag }}" if [ -z "$FLEET_RELEASE_TAG" ]; then - FLEET_RELEASE_TAG=$(git describe --tags "$(git rev-list --tags --max-count=1)") + FLEET_RELEASE_TAG=$(latest_github_tag "Azure/fleet") echo "The user input release tag is empty, will use the latest tag $FLEET_RELEASE_TAG." fi FLEET_NETWORKING_RELEASE_TAG="${{ inputs.fleetNetworkingReleaseTag }}" if [ -z "$FLEET_NETWORKING_RELEASE_TAG" ]; then - FLEET_NETWORKING_RELEASE_TAG=$(curl -sf --retry 3 --retry-delay 5 --retry-all-errors --max-time 30 \ - "https://api.github.com/repos/Azure/fleet-networking/tags" | jq -r '.[0].name') + FLEET_NETWORKING_RELEASE_TAG=$(latest_github_tag "Azure/fleet-networking") echo "The user input fleet-networking release tag is empty, will use the latest tag $FLEET_NETWORKING_RELEASE_TAG." fi