Skip to content

fix: force Docker-compatible manifest media type for multi-platform pushes - #74

Merged
ops-gaurav merged 2 commits into
mainfrom
fix/1210144815075383-docker-oci-mediatype-compat
Jul 28, 2026
Merged

ops-gaurav merged 2 commits into
mainfrom
fix/1210144815075383-docker-oci-mediatype-compat

Conversation

@ramu-n

@ramu-n ramu-n commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • BuildKit's default multi-platform manifest export format silently drifted to OCI image index (application/vnd.oci.image.index.v1+json) between two distribute-api release builds, with zero change to this workflow — traced to the floating moby/buildkit:buildx-stable-1 builder image advancing from v0.30.0 to v0.31.2 between build dates.
  • The legacy Mesos/Marathon deploy fleet runs Docker 17.05.0-ce (2017), which predates OCI manifest support entirely. Pulling an OCI-format image on that host fails with invalid character '<' looking for beginning of value (the daemon can't parse the registry response).
  • push: true in docker/build-push-action@v3 is documented shorthand for --output=type=registry with no media-type control. Replacing it with an explicit outputs: type=registry,oci-mediatypes=false keeps the exact same registry-push exporter already in use, but pins the manifest format to the legacy Docker distribution manifest list (schema2) so it no longer depends on BuildKit's evolving defaults.
  • Confirmed via docker buildx imagetools inspect against the actual registry: known-good tag (rc05) was application/vnd.docker.distribution.manifest.list.v2+json; known-bad tags (rc06, rc07, rc08) were all application/vnd.oci.image.index.v1+json.

Scope

This only touches go_app_release.yml. Existing go/app/v1, go/app/v1.1.x, and go/app/v2 tags are untouched — repos pinned to those are unaffected. Once merged, this will be tagged as a new go/app/v2.1 for distribute-api (and any other repo hitting the same legacy-Docker-host issue) to opt into.

Test plan

  • Confirmed via GitHub Actions logs that docker/build-push-action@v3 accepts outputs alongside provenance: false without conflicting with the removed push input (buildx itself rejects --push + --output together, so push: true must be removed, not just supplemented).
  • Once merged and tagged go/app/v2.1, cut a new distribute-api RC tag against it and confirm the pushed manifest media type is application/vnd.docker.distribution.manifest.list.v2+json via docker buildx imagetools inspect.
  • Confirm the resulting image pulls successfully on the Marathon host.

Ref: ASANA-1210144815075383

🤖 Generated with Claude Code

…ushes

BuildKit's default multi-platform output format silently drifted to
OCI image index (application/vnd.oci.image.index.v1+json) between
builds, with no change to this workflow. Docker Engine versions that
predate OCI manifest support (e.g. the legacy Mesos/Marathon fleet,
running 17.05.0-ce) cannot pull an image published this way and fail
with a JSON-parse error trying to read the registry response.

`push: true` is shorthand for `--output=type=registry`; replacing it
with an explicit `outputs: type=registry,oci-mediatypes=false` keeps
the same registry-push exporter but pins the manifest format to the
legacy Docker distribution manifest list (schema2), regardless of
future BuildKit default changes.

Ref: ASANA-1210144815075383

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Go app release workflow to explicitly force Docker schema2 manifest list media types when pushing multi-platform images, avoiding BuildKit default drift to OCI image indexes that break pulls on legacy Docker daemons.

Changes:

  • Replace push: true with an explicit registry exporter output: outputs: type=registry,oci-mediatypes=false.
  • Keep existing build settings (provenance disabled, multi-platform build, tags/labels) unchanged while pinning the manifest format.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ramu-n
ramu-n requested a review from ops-gaurav July 28, 2026 10:20
@ops-gaurav

ops-gaurav commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

@ramu-n I am not sure if we would want to do that because it would make all docker images non oci format irrespective of marathon/non-marathon environment.

I would recommend a caller input from marathon repos defaulting it to modern behaviour

# go_app_release.yml
  on:
    workflow_call:
      inputs:
        LEGACY_DOCKER_MEDIATYPES:
          description: "Push Docker schema2 manifest lists instead of OCI index (required for legacy Mesos/Marathon Docker 17.x hosts)"
          type: boolean
          default: false
  ...     
  ...
        - name: Build and Push to Artifact Registry
          uses: docker/build-push-action@v3
          with: 
            outputs: type=registry,oci-mediatypes=${{ inputs.LEGACY_DOCKER_MEDIATYPES && 'false' || 'true' }}
            provenance: false

On the distribute side or any other marathon repo, there would be a following change

  name: Release Docker Version
        
  on:
    release:
      types:
        - created
      
  jobs: 
    release:
      uses: Kochava/github-workflows/.github/workflows/go_app_release.yml@go/app/v2.2
      with:
        GH_CI_USER: kochava-ci
        GOPRIVATE: "github.com/Kochava"
        # Marathon fleet runs Docker 17.05, which can't pull OCI image indexes.
        # Remove when apis/distribute moves off Mesos.
        LEGACY_DOCKER_MEDIATYPES: true
      secrets:
        GH_CI_PAT: ${{ secrets.GH_CI_PAT }}
        ARTIFACT_REGISTRY: "us-central1-docker.pkg.dev/ko-o-artreg-f93d/ko-o-docker-arr-uc1"
        ARTIFACT_REGISTRY_JSON_KEY: ${{ secrets.GH_IMG_PUBLISH_JSON_KEY }}

Per review feedback: defaulting every consumer of this tag to legacy
Docker schema2 manifests would silently affect repos that don't run
on Marathon/Mesos and may want OCI-format images for other reasons
(e.g. attestation/scanning tooling).

Add LEGACY_DOCKER_MEDIATYPES (default false, preserving OCI/modern
behavior) so only callers that actually need Docker-compatible
manifests opt in explicitly.

Ref: ASANA-1210144815075383
@ramu-n

ramu-n commented Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

Good point — pushed an update. Added LEGACY_DOCKER_MEDIATYPES as an explicit caller input (default false, so anyone else adopting this tag keeps modern/OCI behavior by default). distribute-api will set it to true when it moves onto this tag (as go/app/v2.1), per your suggested pattern.

@ops-gaurav
ops-gaurav merged commit d70e676 into main Jul 28, 2026
@ops-gaurav
ops-gaurav deleted the fix/1210144815075383-docker-oci-mediatype-compat branch July 28, 2026 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants