Add Github Runner with Cloud Run Worker Pools to Cloud Run samples by sagarrandive · Pull Request #13481 · GoogleCloudPlatform/python-docs-samples · GitHub | Latest TMZ Celebrity News & Gossip | Watch TMZ Live
Skip to content

Add Github Runner with Cloud Run Worker Pools to Cloud Run samples #13481

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

sagarrandive
Copy link

Add Github Runner with Cloud Run Worker Pools to Cloud Run samples. This sample also includes autoscaler for worker pool GH runner using Cloud Run Function

@sagarrandive sagarrandive requested review from a team as code owners July 1, 2025 20:52
@product-auto-label product-auto-label bot added samples Issues that are directly related to samples. api: run Issues related to the Cloud Run API. labels Jul 1, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @sagarrandive, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request adds a new sample to demonstrate how to deploy and manage self-hosted GitHub Actions runners on Google Cloud Run Worker Pools. It includes a robust autoscaling mechanism, powered by a Cloud Function, to efficiently manage runner instances based on the GitHub Actions workflow queue, thereby optimizing resource usage and cost.

Highlights

  • New Sample for GitHub Runners on Cloud Run Worker Pools: This pull request introduces a complete, deployable sample demonstrating how to host self-hosted GitHub Actions runners on Google Cloud Run Worker Pools, leveraging their fast startup and shutdown capabilities for efficient resource utilization.
  • Automated Scaling with Cloud Function: An autoscaling solution is implemented using a Python-based Cloud Function (github-runner-autoscaler/main.py). This function listens to GitHub workflow_job webhooks and dynamically adjusts the manualInstanceCount of the Cloud Run Worker Pool, scaling up runners when jobs are queued and scaling down when jobs complete.
  • Containerized Runner Deployment: The GitHub Actions runner is packaged into a Docker image (run/github-runner/Dockerfile) based on the official actions-runner image. A start.sh script handles the configuration and execution of the runner within the container, including dynamic naming and graceful shutdown.
  • Comprehensive Documentation: A detailed README.md is included, providing step-by-step instructions for setting up the necessary GCP components, IAM roles, deploying the Cloud Run Worker Pool, configuring GitHub secrets, and deploying the autoscaler Cloud Function, along with webhook setup instructions.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request adds a sample for running self-hosted GitHub runners on Cloud Run Worker Pools with an autoscaler. Address the security vulnerability of disabled webhook signature validation, correct the cleanup logic in start.sh and the webhook setup in README.md. Remove dead code and unused dependencies in the autoscaler function.


## Configure the webhook

Under your repository, go to Settings -> Webhooks -> Manage webhook to configure the functions endpoint as the payload URL. Select Push events to trigger the webhook
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

The instruction to select "Push events" for the webhook is incorrect. The autoscaler function handles workflow_job events. Update the documentation to specify workflow_job events.

Suggested change
Under your repository, go to Settings -> Webhooks -> Manage webhook to configure the functions endpoint as the payload URL. Select Push events to trigger the webhook
Under your repository, go to Settings -> Webhooks -> Manage webhook to configure the functions endpoint as the payload URL. Select "Workflow job" events to trigger the webhook

Comment on lines +163 to +169
# 1. Validate Webhook Signature (IMPORTANT FOR PRODUCTION)
# You need to implement this with your GitHub Webhook Secret.
# This is commented out in your original code, but critical for security.
# Example (you need to retrieve webhook_secret from Secret Manager too):
# webhook_secret = get_secret_from_secret_manager("GITHUB_WEBHOOK_SECRET")
# if not validate_signature(request, webhook_secret):
# return ("Invalid signature", 403)
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

Webhook signature validation is commented out, posing a critical security risk. Without validation, anyone can send payloads, triggering the autoscaler. Implement this validation for any real-world usage.



# Configure the current runner instance with URL, token and name.
mkdir /home/docker/actions-runner && cd /home/docker/actions-runner
Copy link
Contributor

Choose a reason for hiding this comment

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

high

This command is unnecessary. The Docker container's working directory is already set to /home/docker/actions-runner. Creating a new directory is not needed and will likely cause the script to fail.

Comment on lines +31 to +49
# Initialize GitHub client
github_client = None
github_entity = None
try:
# Get GH_TOKEN from Secret Manager
client = secretmanager.SecretManagerServiceClient()
secret_name = f"projects/{PROJECT_ID}/secrets/GH_TOKEN/versions/latest"
response = client.access_secret_version(request={"name": secret_name})
gh_token = response.payload.data.decode("UTF-8")
github_client = Github(gh_token)


if RUNNER_SCOPE == 'org':
github_entity = github_client.get_organization(GITHUB_ORG_OR_REPO)
else:
owner, repo_name = GITHUB_ORG_OR_REPO.split('/')
github_entity = github_client.get_user(owner).get_repo(repo_name)
except Exception as e:
logging.error(f"Failed to initialize GitHub client or access GH_TOKEN: {e}")
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The block for initializing the GitHub client, along with the global variables github_client and github_entity, is not used. This is dead code that adds unnecessary complexity and dependencies. Remove this block and the corresponding unused imports.


# Autoscaling parameters
MAX_RUNNERS = int(os.environ.get('MAX_RUNNERS', 5)) # Max number of concurrent runners
IDLE_TIMEOUT_MINUTES = int(os.environ.get('IDLE_TIMEOUT_MINUTES', 15)) # How long to wait before scaling down idle runners
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The configuration variable IDLE_TIMEOUT_MINUTES is defined but not used. Remove this dead code.

"""
auth_req, access_token = get_authenticated_request()
if not access_token:
print("Failed to retrieve Google Cloud access token. Exiting.")
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Use the logging module instead of print for error messages for consistency and better log management.

logging.error("Failed to retrieve Google Cloud access token. Exiting.")

Comment on lines +127 to +136
print(f"Successfully updated Cloud Run worker pool. Status Code: {response.status_code}")
print("Response JSON:")
print(json.dumps(response.json(), indent=2))


except requests.exceptions.RequestException as e:
print(f"Error updating Cloud Run worker pool: {e}")
if response is not None:
print(f"Response Status Code: {response.status_code}")
print(f"Response Text: {response.text}")
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Use the logging module instead of print for all application output to ensure logs are correctly captured, formatted, and routed in a cloud environment. Replace these print calls with logging.info and logging.error.

logging.info(f"Successfully updated Cloud Run worker pool. Status Code: {response.status_code}")
       logging.info("Response JSON:")
       logging.info(json.dumps(response.json(), indent=2))


   except requests.exceptions.RequestException as e:
       logging.error(f"Error updating Cloud Run worker pool: {e}")
       if response is not None:
           logging.error(f"Response Status Code: {response.status_code}")
           logging.error(f"Response Text: {response.text}")

Comment on lines +1 to +7
Flask
requests
google-cloud-secret-manager
google-auth
google-auth-oauthlib
google-api-python-client
PyGithub
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This file contains unused dependencies: google-cloud-secret-manager, google-auth-oauthlib, google-api-python-client, and PyGithub. Removing them will reduce the deployment package size and improve security.

Flask
requests
google-auth

sagarrandive and others added 2 commits July 1, 2025 16:57
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@glasnt glasnt self-assigned this Jul 3, 2025
@glasnt
Copy link
Contributor

glasnt commented Jul 3, 2025

Hi @sagarrandive. This sample might be a bit too complex for this repository. I'll ping you internally on specifics.

@glasnt glasnt added the waiting-response Waiting for the author's response. label Jul 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: run Issues related to the Cloud Run API. samples Issues that are directly related to samples. waiting-response Waiting for the author's response.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants

TMZ Celebrity News – Breaking Stories, Videos & Gossip

Looking for the latest TMZ celebrity news? You've come to the right place. From shocking Hollywood scandals to exclusive videos, TMZ delivers it all in real time.

Whether it’s a red carpet slip-up, a viral paparazzi moment, or a legal drama involving your favorite stars, TMZ news is always first to break the story. Stay in the loop with daily updates, insider tips, and jaw-dropping photos.

🎥 Watch TMZ Live

TMZ Live brings you daily celebrity news and interviews straight from the TMZ newsroom. Don’t miss a beat—watch now and see what’s trending in Hollywood.