Skip to content

output url returns unrelated tag revision url #589

@nakamasato

Description

@nakamasato

TL;DR

When deploying to LATEST=100, if there's another revision tag, the output url can be unrelated revision url.

For example, there's a revision tag called pr-1 with traffic 0, then you deploy a new revision with 100% traffic using revision_traffic: 'LATEST=100' configuration, it runs the following command:

gcloud run services update-traffic my-service --to-latest --format json

The output of the command can be as follows (in the following case the latest revision is the second item of the list):

[
  {
    "displayPercent": "0%",
    "displayRevisionId": "my-service-00429-jog",
    "displayTags": "pr-1",
    "key": "my-service-00429-jog",
    "latestRevision": false,
    "revisionName": "my-service-00429-jog",
    "serviceUrl": "https://my-service-xxxxxx-an.a.run.app",
    "specPercent": "0",
    "specTags": "pr-1",
    "statusPercent": "0",
    "statusTags": "pr-1",
    "tags": [
      {
        "inSpec": true,
        "inStatus": true,
        "tag": "pr-415",
        "url": "https://pr-1---my-service-xxxxxx-an.a.run.app"
      }
    ],
    "urls": [
      "https://pr-1---my-service-xxxxxx-an.a.run.app"
    ]
  },
  {
    "displayPercent": "100%",
    "displayRevisionId": "LATEST (currently my-service-00374-kdw)",
    "displayTags": "dev",
    "key": "LATEST",
    "latestRevision": true,
    "revisionName": "my-service-00374-kdw",
    "serviceUrl": "https://my-service-xxxxxxx-an.a.run.app",
    "specPercent": "100",
    "specTags": "dev",
    "statusPercent": "100",
    "statusTags": "dev",
    "tags": [
      {
        "inSpec": true,
        "inStatus": true,
        "tag": "dev",
        "url": "https://dev---my-service-xxxxxx-an.a.run.app"
      }
    ],
    "urls": [
      "https://dev---my-service-xxxxxx-an.a.run.app"
    ]
  }
]

However the current logic always takes the first url, so the returned url can be completely unrelated to the deploy-cloudrun action.

// Maintain current logic to use first tag URL if present
for (const item of outputJSON) {
if (item?.urls?.length) {
url = item.urls[0];
break;
}
}

Expected behavior

The URL for the latest revision is returned.

Observed behavior

Unrelated revision url is returned

Action YAML

name: "Enhanced Cloud Run Deploy"
description: "Deploy to Google Cloud Run with advanced PR and traffic management features"
author: "nakamasato"

inputs:
  # Inputs passed through to google-github-actions/deploy-cloudrun@v3
  service:
    description: "Cloud Run service name"
    required: true
  image:
    description: "Container image URL"
    required: true
  source:
    description: "Path to source code for deployment"
    required: false
  suffix:
    description: "Revision name suffix"
    required: false
  env_vars:
    description: "Environment variables in KEY=VALUE format (one per line)"
    required: false
  env_vars_update_strategy:
    description: "Strategy for updating environment variables"
    required: false
    default: "merge"
  secrets:
    description: "Secrets in KEY=SECRET_NAME format (one per line)"
    required: false
  secrets_update_strategy:
    description: "Strategy for updating secrets"
    required: false
    default: "merge"
  labels:
    description: "Service labels"
    required: false
  skip_default_labels:
    description: "Skip automatic GitHub Actions labels"
    required: false
    default: "false"
  timeout:
    description: "Maximum request execution time"
    required: false
  flags:
    description: "Additional Cloud Run deployment flags"
    required: false
  tag_traffic:
    description: "Tag traffic assignments"
    required: false
  project_id:
    description: "Google Cloud project ID"
    required: true
  region:
    description: "Google Cloud region"
    required: true
  gcloud_version:
    description: "Cloud SDK version"
    required: false
  gcloud_component:
    description: "Cloud SDK components to install"
    required: false

  # Specify default values
  no_traffic:
    description: "Deploy with no traffic allocation"
    required: false
    default: ${{ github.event_name == 'pull_request' }}
  revision_traffic:
    description: "Traffic allocation for the deployed revision"
    required: false
    default: ${{ github.event_name != 'pull_request' && 'LATEST=100' || '' }}
  tag:
    description: "Traffic tag for the revision"
    required: false
    default: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || '' }}

  # Additional inputs specific to this action
  github_token:
    description: "GitHub token for PR comments (required for PR deployments)"
    required: false
    default: ${{ github.token }}
  pr_comment_marker:
    description: "HTML comment marker to identify PR comments for updates"
    required: false
    default: "deploy-cloudrun-comment"

outputs:
  url:
    description: "Service URL"
    value: ${{ steps.deploy.outputs.url }}
  revision:
    description: "Deployed revision name"
    value: ${{ steps.deploy.outputs.revision }}

runs:
  using: "composite"
  steps:
    - name: Deploy to Cloud Run
      id: deploy
      uses: google-github-actions/deploy-cloudrun@2028e2d7d30a78c6910e0632e48dd561b064884d # v3.0.1
      with:
        service: ${{ inputs.service }}
        image: ${{ inputs.image }}
        source: ${{ inputs.source }}
        suffix: ${{ inputs.suffix }}
        env_vars: ${{ inputs.env_vars }}
        env_vars_update_strategy: ${{ inputs.env_vars_update_strategy }}
        secrets: ${{ inputs.secrets }}
        secrets_update_strategy: ${{ inputs.secrets_update_strategy }}
        labels: ${{ inputs.labels }}
        skip_default_labels: ${{ inputs.skip_default_labels }}
        tag: ${{ inputs.tag }}
        timeout: ${{ inputs.timeout }}
        flags: ${{ inputs.flags }}
        no_traffic: ${{ inputs.no_traffic }}
        revision_traffic: ${{ inputs.revision_traffic }}
        tag_traffic: ${{ inputs.tag_traffic }}
        project_id: ${{ inputs.project_id }}
        region: ${{ inputs.region }}
        gcloud_version: ${{ inputs.gcloud_version }}
        gcloud_component: ${{ inputs.gcloud_component }}

    - name: Find existing PR comment
      if: github.event_name == 'pull_request' && inputs.github_token != ''
      uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4.0.0
      id: find-comment
      with:
        issue-number: ${{ github.event.pull_request.number }}
        comment-author: 'github-actions[bot]'
        body-includes: ${{ inputs.pr_comment_marker }}

    - name: Create or update PR comment
      if: github.event_name == 'pull_request' && inputs.github_token != ''
      uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0
      with:
        token: ${{ inputs.github_token }}
        comment-id: ${{ steps.find-comment.outputs.comment-id }}
        issue-number: ${{ github.event.pull_request.number }}
        edit-mode: replace
        body: |
          <!-- ${{ inputs.pr_comment_marker }} -->
          ## 🚀 Cloud Run Deployment Preview

          Your PR has been deployed to Cloud Run!

          **🌐 Preview URL:** ${{ steps.deploy.outputs.url }}
          **🏷️ Revision:** ${{ steps.deploy.outputs.revision }}

          > ⚠️ This deployment receives **0% traffic** and is only accessible via the preview URL above.

          <details>
          <summary>📋 Deployment Details</summary>

          | Property | Value |
          |----------|-------|
          | **Service** | ${{ inputs.service }} |
          | **Region** | ${{ inputs.region }} |
          | **Tag** | ${{ inputs.tag }} |
          | **Image** | ${{ inputs.image }} |
          | **Service URL** | ${{ steps.deploy.outputs.url }} |
          | **Traffic Allocation** | 0% (tagged deployment) |

          </details>

          <details>
          <summary>🔗 Useful Links</summary>

          - [Cloud Run Console](https://console.cloud.google.com/run/detail/${{ inputs.region }}/${{ inputs.service }}?project=${{ inputs.project_id }})
          - [Service Logs](https://console.cloud.google.com/logs/query;query=resource.type%3D%22cloud_run_revision%22%0Aresource.labels.service_name%3D%22${{ inputs.service }}%22?project=${{ inputs.project_id }})

          </details>

          ---
          [Run #${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})


    - name: Output deployment summary
      shell: bash
      run: |
        echo "## 🚀 Deployment Summary" >> $GITHUB_STEP_SUMMARY
        echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY
        echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
        echo "| Service | ${{ inputs.service }} |" >> $GITHUB_STEP_SUMMARY
        echo "| Region | ${{ inputs.region }} |" >> $GITHUB_STEP_SUMMARY
        echo "| Deployment Type | ${{ github.event_name }} |" >> $GITHUB_STEP_SUMMARY
        echo "| Image | ${{ inputs.image }} |" >> $GITHUB_STEP_SUMMARY
        echo "| Service URL | ${{ steps.deploy.outputs.url }} |" >> $GITHUB_STEP_SUMMARY

        if [ "${{ github.event_name }}" = "pull_request" ]; then
          echo "| PR URL | ${{ steps.deploy.outputs.url }} |" >> $GITHUB_STEP_SUMMARY
          echo "| Traffic Allocation | 0% (tagged as ${{ inputs.tag }}) |" >> $GITHUB_STEP_SUMMARY
        else
          echo "| Traffic Allocation | 100% |" >> $GITHUB_STEP_SUMMARY
        fi

        echo "" >> $GITHUB_STEP_SUMMARY
        echo "✅ Deployment completed successfully!" >> $GITHUB_STEP_SUMMARY

branding:
  icon: "cloud"
  color: "blue"

Log output


Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions