HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
actions
runner
C#2019–2026
actions / runner

runner

The Runner for GitHub Actions :rocket:

58Distinct people
61Mentions
0Explicit recommenders
6.4KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

The Runner for GitHub Actions :rocket:

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 12:54:37 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year61 dated mentions

Observed mentions: 2019-12-19 20:05:01 UTC to 2026-06-05 15:47:59 UTC.

05101520252019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments20192020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 9 mentions; 0 submissions, 9 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 7 mentions; 1 submissions, 6 comments20222023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 8 mentions; 2 submissions, 6 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 2 mentions; 1 submissions, 1 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 25 mentions; 5 submissions, 20 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 6 mentions; 0 submissions, 6 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC202
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC202
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC909
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC716
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC826
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC211
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC25520
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC606

From the project README

An excerpt from the repository, fetched Nov 13, 2026.

Read the project’s introduction
GitHub Actions Runner The runner is the application that runs a job from a GitHub Actions workflow. It is used by GitHub Actions in the hosted virtual environments, or you can self-host the runner in your own environment. Get Started For more information about installing and using self-hosted runners, see Adding self-hosted runners and Using self-hosted runners in a workflow Runner releases: Pre-reqs | Download Pre-reqs | Download Pre-reqs | Download Note Thank you for your interest in this GitHub repo, however, right now we are not taking contributions. We continue to focus our resources on strategic areas that help our customers be successful while making developers' lives easier. While GitHub Actions remains a key part of this vision, we are allocating resources towards other areas of Actions and are not taking contributions to this repository at this time. The GitHub public roadmap is the best place to follow along for any updates on features we’re working on and what stage they’re in. We are taking the following steps to better direct requests related to GitHub Actions, including: We will be directing questions and support requests to our Community Discussions area High Priority bugs can be reported through Community Discussions or you can report these to our support team https://support.github.com/contact/bug-report. Security Issues should be handled as per our SECURITY.md We will still provide security updates for this project and fix major breaking changes during this time. You are welcome to still raise bugs in this repo.
Read the full README on GitHub

What Hacker News says

61 sources
Take the JS file and decode it! Decoded execution chain ----------------------- 1. Outer layer: - Starts with try{eval(function(s,n){...})([large numeric array].map(...).join(""),1)) - Converts numeric character codes into a string. - Applies a Caesar +1 shift to alphabetic characters. - eval() executes the decoded layer. 2. First decoded layer: - Imports node:crypto. - Defines an AES-128-GCM decryptor. - Decrypts two embedded payloads: a) _b: small Bun bootstrap/loader b) _p: large obfuscated payload (~686 KB) - Writes _p to a temporary JS file under /tmp/p<random>.js. - If Bun is available, runs: bun run "<temp file>" - If Bun is unavailable, downloads Bun from GitHub releases and then runs the payload. 3. Small loader payload: - Downloads Bun v1.3.13 from: https://github.com/oven-sh/bun/r
Read the rest
eleases/download/bun-v1.3.13... - Uses curl and unzip. - Creates temporary directories under /tmp/b-* - Runs the large payload using Bun. 4. Large payload: - Obfuscated JavaScript with a string-table decoder and a second custom encrypted string layer. - After decoding strings, the payload clearly contains credential and secret collection logic. Observed behaviour / capabilities --------------------------------- The payload appears to collect or search for: - GitHub tokens / PATs / GitHub Actions OIDC tokens - npm tokens and npm OIDC package exchange tokens - RubyGems API keys - AWS credentials, STS metadata credentials and Secrets Manager secrets - Azure credentials, service principals and Key Vault secrets - GCP service account tokens and Secret Manager secrets - Vault tokens and Vault secrets - Kubernetes service account tokens and kubeconfig - Docker credentials - SSH keys and config - Git credentials - .env files and common project secrets - Claude configuration and project files - OnePassword items via the op CLI - Slack, Discord, Signal, Telegram and Element local data - Crypto wallet files such as Exodus, Ledger Live, Ethereum keystores and Monero data - Shell and database history files Exfiltration / persistence style -------------------------------- The payload contains logic to: - Create or use GitHub repositories through GitHub API endpoints. - Commit collected data/content into repository files. - Add/update files such as: - .vscode/tasks.json - .claude/index.js - .claude/settings.json - .claude/setup.mjs - .vscode/setup.mjs - Use commit messages such as: - chore: update dependencies - create del-commit: - Create a GitHub repo with description: - Hades - The End for the Damned - Use api.anthropic.com with path v1/api as an apparent outbound endpoint. - Use a token/string: - IfYouYankThisTokenItWillNukeTheComputerOfTheOwnerFully Notable URLs / endpoints ------------------------ - https://api.github.com - https://api.github.com/graphql - https://github.com/ - https://github.com/actions/runner - https://github.com/oven-sh/bun/releases/download/bun-v1.3.13... - https://registry.npmjs.org/ - https://registry.npmjs.org/-/npm/v1/oidc/token/exchange/pack... - https://registry.npmjs.org/-/npm/v1/tokens - https://registry.npmjs.org/-/whoami - https://rubygems.org/api/v1/api_key.json - https://rubygems.org/api/v1/gems - https://cloudresourcemanager.googleapis.com/v1 - https://secretmanager.googleapis.com/v1 - https://graph.microsoft.com/v1.0/me - https://login.microsoftonline.com/ - https://vault.azure.net/.default - http://169.254.169.254/latest/api/token - http://169.254.169.254/latest/meta-data/iam/security-credent... - http://169.254.170.2 - http://127.0.0.1:8200 - api.anthropic.com / v1/api Files/globs targeted -------------------- - */.env - */.env.local - */.env.production - */.git/config - */config/database.yml - */wp-config.php - .env - .git-credentials - .npmrc - ~/.npmrc - ~/.pypirc - ~/.yarnrc - ~/.aws/config - ~/.aws/credentials - ~/.azure/accessTokens.json - ~/.azure/msal_token_cache.* - ~/.config/gcloud/access_tokens.db - ~/.config/gcloud/application_default_credentials.json - ~/.config/gcloud/credentials.db - ~/.docker/config.json - ~/.docker//config.json - /root/.docker/config.json - ~/.kube/config - /etc/rancher/k3s/k3s.yaml - /var/run/secrets/kubernetes.io/serviceaccount/token - ~/.terraform.d/credentials.tfrc.json - ~/.ssh/id - ~/.ssh/id_rsa - ~/.ssh/id_ed25519 - ~/.ssh/id_ecdsa - ~/.ssh/config - ~/.ssh/known_hosts - ~/.gitconfig - ~/.config/git/credentials - ~/.netrc - ~/.bash_history - ~/.zsh_history - ~/.python_history - ~/.psql_history - ~/.mysql_history - ~/.claude.json - ~/.claude/* - ~/.claude/projects/* - ~/.claude/mcp.json - %USERPROFILE%\.claude.json - %USERPROFILE%\.claude* - ~/.config/Slack/Cookies - ~/.config/discord/Local Storage/leveldb/* - ~/.config/Signal/* - ~/.local/share/TelegramDesktop/tdata/* - ~/.config/Element/Local Storage/* - ~/.config/Exodus/exodus.wallet/* - ~/.config/Ledger Live/* - ~/.ethereum/keystore/* - ~/.monero/* - ~/.local/share/keyrings/.keyring - ~/.kde/share/apps/kwallet/.kwl - ~/.config/filezilla/sitemanager.xml - ~/.config/filezilla/recentservers.xml Environment variables checked ----------------------------- - GITHUB_ACTIONS - GITHUB_REPOSITORY - GITHUB_REF - ACTIONS_ID_TOKEN_REQUEST_URL - ACTIONS_ID_TOKEN_REQUEST_TOKEN - TARGET_REPOS - AWS_ACCESS_KEY_ID - AWS_SECRET_ACCESS_KEY - AWS_SESSION_TOKEN - AWS_PROFILE - AWS_REGION - AWS_DEFAULT_REGION - AWS_WEB_IDENTITY_TOKEN_FILE - AWS_CONTAINER_CREDENTIALS_RELATIVE_URI - AWS_CONTAINER_CREDENTIALS_FULL_URI - AWS_CONTAINER_AUTHORIZATION_TOKEN - AZURE_TENANT_ID - AZURE_CLIENT_ID - AZURE_CLIENT_SECRET - AZURE_FEDERATED_TOKEN_FILE - AZURE_KEY_VAULT_NAME - GOOGLE_APPLICATION_CREDENTIALS - GOOGLE_CLOUD_PROJECT - GCP_PROJECT - GCLOUD_PROJECT - KUBECONFIG - VAULT_ADDR - VAULT_API_TOKEN - VAULT_TOKEN_FILE - VAULT_TOKEN_PATH - VAULT_AWS_ROLE - VAULT_ROLE - HOME - USERPROFILE - LANG / LANGUAGE / LC_ALL / LC_MESSAGES (edited)
In Supply chain attack alert: .github/setup.js
Oh man, I'd actually forgotten about that! What's hilarious about that script is that the solution is so simple: use a less-than comparison instead of an equals. That's really, really all it would have taken to fix the issue. And yet https://github.com/actions/runner/pull/3157 was opened on 2024-02-17 and was merged on 2025-08-21, a full 18 months (plus a few days) later! It took literally 18 months for them to merge a bugfix that is trivially obvious to see is correct. Yeah, the problems at GitHub ran (and still run) deep. P.S. Yes, there are busy-wait issues in that code, which should have been addressed by bringing back the check for the `sleep` command and using it if available, falling back on the CPU-burning busy-wait only if `sleep` was unavailable. But the most revealing thing is the 18 months to merge a trivial-to-verify PR. That
Read the rest
, more than the bad busy-wait loop, is the fundamental indicator of brokenness at GitHub under Microsoft's ownership.
In Ghostty is leaving GitHub
It was the safe_sleep function. Here's an issue on it [0]. IIRC there was an early issue, but really this is code that never should have made it in. Here's the conditional in question SECONDS=0 while [[ $SECONDS -lt $1 ]]; do : done Here's the fix... (s/!=/-lt) while [[ $SECONDS -lt $1 ]]; It's a fallback sleep function for if you don't have the sleep command, (or read, or ping) then it'll increment SECONDS (special variable) until the time has passed because : does nothing (it will peg your CPU though). Problem is the loop isn't computed with infinite precision. Doesn't take a genius to figure out < is infinitely better than != here and you'd be right to guess that people did in fact waste thousands of dollars getting stuck in infinite loops that were entirely unavoidable. Here's the actual merge...[1] At least it didn't
Read the rest
take them months to merge this line, which should have existed from day 1 too (a very very well known pattern for writing bash scripts)[2] [0] https://github.com/actions/runner/issues/3792 [1] https://github.com/actions/runner/pull/3157/changes [2] https://github.com/meshtastic/firmware/pull/7922
In Glassworm is back: A new wave of invisible Unicode attacks hits repositories
This is 1/3 response to a short prompt about implementation options for GitHub Runner form broken Server to Github Enterprise Cloud: # EC2-Based GitHub Actions Self-Hosted Runners - Complete Implementation ## Architecture Overview This solution deploys auto-scaling GitHub Actions runners on EC2 instances that can trigger your existing AWS CodeBuild pipelines. Runners are managed via Auto Scaling Groups with automatic registration and health monitoring. ## Prerequisites - AWS CLI configured with appropriate credentials - GitHub Enterprise Cloud organization admin access - Existing CodeBuild project(s) - VPC with public/private subnets ## Solution Components ### 1. CloudFormation Template### 2. GitHub Workflow for CodeBuild Integration## Deployment Steps ### Step 1: Create GitHub Personal Access Token 1. Navigate to GitHub → Settings → Deve
Read the rest
loper settings → Personal access tokens → Fine-grained tokens 2. Create token with these permissions: - *Repository permissions:* - Actions: Read and write - Metadata: Read - *Organization permissions:* - Self-hosted runners: Read and write ```bash # Store token securely export GITHUB_PAT="ghp_xxxxxxxxxxxxxxxxxxxx" export GITHUB_ORG="your-org-name" ``` ### Step 2: Deploy CloudFormation Stack ```bash # Set variables export AWS_REGION=us-east-1 export STACK_NAME=github-runner-ec2 export VPC_ID=vpc-xxxxxxxx export SUBNET_IDS="subnet-xxxxxxxx,subnet-yyyyyyyy" # Deploy stack aws cloudformation create-stack \ --stack-name $STACK_NAME \ --template-body file://github-runner-ec2-asg.yaml \ --parameters \ ParameterKey=VpcId,ParameterValue=$VPC_ID \ ParameterKey=PrivateSubnetIds,ParameterValue=\"$SUBNET_IDS\" \ ParameterKey=GitHubOrganization,ParameterValue=$GITHUB_ORG \ ParameterKey=GitHubPAT,ParameterValue=$GITHUB_PAT \ ParameterKey=InstanceType,ParameterValue=t3.medium \ ParameterKey=MinSize,ParameterValue=2 \ ParameterKey=MaxSize,ParameterValue=10 \ ParameterKey=DesiredCapacity,ParameterValue=2 \ ParameterKey=RunnerLabels,ParameterValue="self-hosted,linux,x64,ec2,aws,codebuild" \ ParameterKey=CodeBuildProjectNames,ParameterValue="" \ --capabilities CAPABILITY_NAMED_IAM \ --region $AWS_REGION # Wait for completion (5-10 minutes) aws cloudformation wait stack-create-complete \ --stack-name $STACK_NAME \ --region $AWS_REGION # Get stack outputs aws cloudformation describe-stacks \ --stack-name $STACK_NAME \ --query 'Stacks[0].Outputs' \ --region $AWS_REGION ``` ### Step 3: Verify Runners ```bash # Check Auto Scaling Group ASG_NAME=$(aws cloudformation describe-stacks \ --stack-name $STACK_NAME \ --query 'Stacks[0].Outputs[?OutputKey==`AutoScalingGroupName`].OutputValue' \ --output text) aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names $ASG_NAME \ --region $AWS_REGION # List running instances aws ec2 describe-instances \ --filters "Name=tag:aws:autoscaling:groupName,Values=$ASG_NAME" \ --query 'Reservations[].Instances[].[InstanceId,State.Name,PrivateIpAddress]' \ --output table # Check CloudWatch logs aws logs tail /github-runner/instances --follow ``` ### Step 4: Verify in GitHub Navigate to: `https://github.com/organizations/YOUR_ORG/settings/actions/r...` You should see your EC2 runners listed as "Idle" with labels: `self-hosted, linux, x64, ec2, aws, codebuild` ## Using One Runner for Multiple Repos & Pipelines ### Organization-Level Runners (Recommended) EC2 runners registered at the organization level can serve all repositories automatically. *Benefits:* - Centralized management - Cost-efficient resource sharing - Simplified scaling - Single point of monitoring *Configuration in CloudFormation:* The template already configures organization-level runners via the UserData script: ```bash ./config.sh --url "https://github.com/${GitHubOrganization}" ... ``` ### Multi-Repository Workflow Examples### Advanced: Runner Groups for Access Control### Label-Based Runner Selection Strategy *Create different runner pools with specific labels:* ```bash # Production runners RunnerLabels: "self-hosted,linux,ec2,production,high-performance" # Development runners RunnerLabels: "self-hosted,linux,ec2,development,general" # Team-specific runners RunnerLabels: "self-hosted,linux,ec2,team-platform,specialized" ``` *Use in workflows:* ```yaml jobs: prod-deploy: runs-on: [self-hosted, linux, ec2, production] dev-test: runs-on: [self-hosted, linux, ec2, development] platform-build: runs-on: [self-hosted, linux, ec2, team-platform] ``` ## Monitoring and Maintenance ### Monitor Runner Health ```bash # Check Auto Scaling Group health aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names $ASG_NAME \ --query 'AutoScalingGroups[0].[DesiredCapacity,MinSize,MaxSize,Instances[].[InstanceId,HealthStatus,LifecycleState]]' # View instance system logs INSTANCE_ID=$(aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names $ASG_NAME \ --query 'AutoScalingGroups[0].Instances[0].InstanceId' \ --output text) aws ec2 get-console-output --instance-id $INSTANCE_ID # Check CloudWatch logs aws logs get-log-events \ --log-group-name /github-runner/instances \ --log-stream-name $INSTANCE_ID/runner \ --limit 50 ``` ### Connect to Runner Instance (via SSM) ```bash # List instances aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names $ASG_NAME \ --query 'AutoScalingGroups[0].Instances[].[InstanceId,HealthStatus]' \ --output table # Connect via Session Manager (no SSH key needed) aws ssm start-session --target $INSTANCE_ID # Once connected, check runner status sudo systemctl status actions.runner. sudo journalctl -u actions.runner.* -f ``` ### Troubleshooting Common Issues## Advanced Scaling Configuration ### Lambda-Based Dynamic Scaling For more sophisticated scaling based on GitHub Actions queue depth:### Deploy Scaling Lambda ```bash # Create Lambda function zip function.zip github-queue-scaler.py aws lambda create-function \ --function-name github-runner-scaler \ --runtime python3.11 \ --role arn:aws:iam::ACCOUNT_ID:role/lambda-execution-role \ --handler github-queue-scaler.lambda_handler \ --zip-file fileb://function.zip \ --timeout 30 \ --environment Variables="{ ASG_NAME=$ASG_NAME, GITHUB_ORG=$GITHUB_ORG, GITHUB_TOKEN=$GITHUB_PAT, MAX_RUNNERS=10, MIN_RUNNERS=2 }" # Create CloudWatch Events rule to trigger every 2 minutes aws events put-rule \ --name github-runner-scaling \ --schedule-expression 'rate(2 minutes)' aws events put-targets \ --rule github-runner-scaling \ --targets "Id"="1","Arn"="arn:aws:lambda:REGION:ACCOUNT:function:github-runner-scaler" ``` ## Cost Optimization ### 1. Use Spot Instances Add to Launch Template in CloudFormation: ```yaml LaunchTemplateData: InstanceMarketOptions: MarketType: spot SpotOptions: MaxPrice: "0.05" # Set max price SpotInstanceType: one-time ``` ### 2. Scheduled Scaling Scale down during off-hours: ```bash # Scale down at night (9 PM) aws autoscaling put-scheduled-action \ --auto-scaling-group-name $ASG_NAME \ --scheduled-action-name scale-down-night \ --recurrence "0 21 * * " \ --desired-capacity 1 # Scale up in morning (7 AM) aws autoscaling put-scheduled-action \ --auto-scaling-group-name $ASG_NAME \ --scheduled-action-name scale-up-morning \ --recurrence "0 7 * MON-FRI" \ --desired-capacity 3 ``` ### 3. Instance Type Mix Use multiple instance types for better availability and cost: ```yaml MixedInstancesPolicy: InstancesDistribution: OnDemandBaseCapacity: 1 OnDemandPercentageAboveBaseCapacity: 25 SpotAllocationStrategy: price-capacity-optimized LaunchTemplate: Overrides: - InstanceType: t3.medium - InstanceType: t3a.medium - InstanceType: t2.medium ``` ## Security Best Practices 1. *No hardcoded credentials* - Using Secrets Manager for GitHub PAT 2. *IMDSv2 enforced* - Prevents SSRF attacks 3. *Minimal IAM permissions* - Scoped to specific CodeBuild projects 4. *Private subnets* - Runners not directly accessible from internet 5. *SSM for access* - No SSH keys needed 6. *Encrypted secrets* - Secrets Manager encryption at rest 7. *CloudWatch logging* - All runner activity logged ## References - [GitHub Self-hosted Runners Documentation](https://docs.github.com/en/actions/hosting-your-own-runners/...) - [GitHub Runner Registration API](https://docs.github.com/en/rest/actions/self-hosted-runners) - [AWS Auto Scaling Documentation](https://docs.aws.amazon.com/autoscaling/ec2/userguide/what-i...) - [AWS CodeBuild API Reference](https://docs.aws.amazon.com/codebuild/latest/APIReference/We...) - [GitHub Actions Runner Releases](https://github.com/actions/runner/releases) - [AWS Systems Manager Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide...) This solution provides a production-ready, cost-effective EC2-based runner infrastructure with automatic scaling, comprehensive monitoring, and multi-repository support for triggering CodeBuild pipelines.
In Ask HN: Do you have any evidence that agentic coding works?
claude response to a query to give options for GitHub runner ... it haas generated 3 more files to review test and make it work: # EC2-Based GitHub Actions Self-Hosted Runners - Complete Implementation ## Architecture Overview This solution deploys auto-scaling GitHub Actions runners on EC2 instances that can trigger your existing AWS CodeBuild pipelines. Runners are managed via Auto Scaling Groups with automatic registration and health monitoring. ## Prerequisites - AWS CLI configured with appropriate credentials - GitHub Enterprise Cloud organization admin access - Existing CodeBuild project(s) - VPC with public/private subnets ## Solution Components ### 1. CloudFormation Template### 2. GitHub Workflow for CodeBuild Integration## Deployment Steps ### Step 1: Create GitHub Personal Access Token 1. Navigate to GitHub → Settings → Develope
Read the rest
r settings → Personal access tokens → Fine-grained tokens 2. Create token with these permissions: - *Repository permissions:* - Actions: Read and write - Metadata: Read - *Organization permissions:* - Self-hosted runners: Read and write ```bash # Store token securely export GITHUB_PAT="ghp_xxxxxxxxxxxxxxxxxxxx" export GITHUB_ORG="your-org-name" ``` ### Step 2: Deploy CloudFormation Stack ```bash # Set variables export AWS_REGION=us-east-1 export STACK_NAME=github-runner-ec2 export VPC_ID=vpc-xxxxxxxx export SUBNET_IDS="subnet-xxxxxxxx,subnet-yyyyyyyy" # Deploy stack aws cloudformation create-stack \ --stack-name $STACK_NAME \ --template-body file://github-runner-ec2-asg.yaml \ --parameters \ ParameterKey=VpcId,ParameterValue=$VPC_ID \ ParameterKey=PrivateSubnetIds,ParameterValue=\"$SUBNET_IDS\" \ ParameterKey=GitHubOrganization,ParameterValue=$GITHUB_ORG \ ParameterKey=GitHubPAT,ParameterValue=$GITHUB_PAT \ ParameterKey=InstanceType,ParameterValue=t3.medium \ ParameterKey=MinSize,ParameterValue=2 \ ParameterKey=MaxSize,ParameterValue=10 \ ParameterKey=DesiredCapacity,ParameterValue=2 \ ParameterKey=RunnerLabels,ParameterValue="self-hosted,linux,x64,ec2,aws,codebuild" \ ParameterKey=CodeBuildProjectNames,ParameterValue="" \ --capabilities CAPABILITY_NAMED_IAM \ --region $AWS_REGION # Wait for completion (5-10 minutes) aws cloudformation wait stack-create-complete \ --stack-name $STACK_NAME \ --region $AWS_REGION # Get stack outputs aws cloudformation describe-stacks \ --stack-name $STACK_NAME \ --query 'Stacks[0].Outputs' \ --region $AWS_REGION ``` ### Step 3: Verify Runners ```bash # Check Auto Scaling Group ASG_NAME=$(aws cloudformation describe-stacks \ --stack-name $STACK_NAME \ --query 'Stacks[0].Outputs[?OutputKey==`AutoScalingGroupName`].OutputValue' \ --output text) aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names $ASG_NAME \ --region $AWS_REGION # List running instances aws ec2 describe-instances \ --filters "Name=tag:aws:autoscaling:groupName,Values=$ASG_NAME" \ --query 'Reservations[].Instances[].[InstanceId,State.Name,PrivateIpAddress]' \ --output table # Check CloudWatch logs aws logs tail /github-runner/instances --follow ``` ### Step 4: Verify in GitHub Navigate to: `https://github.com/organizations/YOUR_ORG/settings/actions/r...` You should see your EC2 runners listed as "Idle" with labels: `self-hosted, linux, x64, ec2, aws, codebuild` ## Using One Runner for Multiple Repos & Pipelines ### Organization-Level Runners (Recommended) EC2 runners registered at the organization level can serve all repositories automatically. *Benefits:* - Centralized management - Cost-efficient resource sharing - Simplified scaling - Single point of monitoring *Configuration in CloudFormation:* The template already configures organization-level runners via the UserData script: ```bash ./config.sh --url "https://github.com/${GitHubOrganization}" ... ``` ### Multi-Repository Workflow Examples### Advanced: Runner Groups for Access Control### Label-Based Runner Selection Strategy *Create different runner pools with specific labels:* ```bash # Production runners RunnerLabels: "self-hosted,linux,ec2,production,high-performance" # Development runners RunnerLabels: "self-hosted,linux,ec2,development,general" # Team-specific runners RunnerLabels: "self-hosted,linux,ec2,team-platform,specialized" ``` *Use in workflows:* ```yaml jobs: prod-deploy: runs-on: [self-hosted, linux, ec2, production] dev-test: runs-on: [self-hosted, linux, ec2, development] platform-build: runs-on: [self-hosted, linux, ec2, team-platform] ``` ## Monitoring and Maintenance ### Monitor Runner Health ```bash # Check Auto Scaling Group health aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names $ASG_NAME \ --query 'AutoScalingGroups[0].[DesiredCapacity,MinSize,MaxSize,Instances[].[InstanceId,HealthStatus,LifecycleState]]' # View instance system logs INSTANCE_ID=$(aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names $ASG_NAME \ --query 'AutoScalingGroups[0].Instances[0].InstanceId' \ --output text) aws ec2 get-console-output --instance-id $INSTANCE_ID # Check CloudWatch logs aws logs get-log-events \ --log-group-name /github-runner/instances \ --log-stream-name $INSTANCE_ID/runner \ --limit 50 ``` ### Connect to Runner Instance (via SSM) ```bash # List instances aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-names $ASG_NAME \ --query 'AutoScalingGroups[0].Instances[].[InstanceId,HealthStatus]' \ --output table # Connect via Session Manager (no SSH key needed) aws ssm start-session --target $INSTANCE_ID # Once connected, check runner status sudo systemctl status actions.runner. sudo journalctl -u actions.runner.* -f ``` ### Troubleshooting Common Issues## Advanced Scaling Configuration ### Lambda-Based Dynamic Scaling For more sophisticated scaling based on GitHub Actions queue depth:### Deploy Scaling Lambda ```bash # Create Lambda function zip function.zip github-queue-scaler.py aws lambda create-function \ --function-name github-runner-scaler \ --runtime python3.11 \ --role arn:aws:iam::ACCOUNT_ID:role/lambda-execution-role \ --handler github-queue-scaler.lambda_handler \ --zip-file fileb://function.zip \ --timeout 30 \ --environment Variables="{ ASG_NAME=$ASG_NAME, GITHUB_ORG=$GITHUB_ORG, GITHUB_TOKEN=$GITHUB_PAT, MAX_RUNNERS=10, MIN_RUNNERS=2 }" # Create CloudWatch Events rule to trigger every 2 minutes aws events put-rule \ --name github-runner-scaling \ --schedule-expression 'rate(2 minutes)' aws events put-targets \ --rule github-runner-scaling \ --targets "Id"="1","Arn"="arn:aws:lambda:REGION:ACCOUNT:function:github-runner-scaler" ``` ## Cost Optimization ### 1. Use Spot Instances Add to Launch Template in CloudFormation: ```yaml LaunchTemplateData: InstanceMarketOptions: MarketType: spot SpotOptions: MaxPrice: "0.05" # Set max price SpotInstanceType: one-time ``` ### 2. Scheduled Scaling Scale down during off-hours: ```bash # Scale down at night (9 PM) aws autoscaling put-scheduled-action \ --auto-scaling-group-name $ASG_NAME \ --scheduled-action-name scale-down-night \ --recurrence "0 21 * * " \ --desired-capacity 1 # Scale up in morning (7 AM) aws autoscaling put-scheduled-action \ --auto-scaling-group-name $ASG_NAME \ --scheduled-action-name scale-up-morning \ --recurrence "0 7 * MON-FRI" \ --desired-capacity 3 ``` ### 3. Instance Type Mix Use multiple instance types for better availability and cost: ```yaml MixedInstancesPolicy: InstancesDistribution: OnDemandBaseCapacity: 1 OnDemandPercentageAboveBaseCapacity: 25 SpotAllocationStrategy: price-capacity-optimized LaunchTemplate: Overrides: - InstanceType: t3.medium - InstanceType: t3a.medium - InstanceType: t2.medium ``` ## Security Best Practices 1. *No hardcoded credentials* - Using Secrets Manager for GitHub PAT 2. *IMDSv2 enforced* - Prevents SSRF attacks 3. *Minimal IAM permissions* - Scoped to specific CodeBuild projects 4. *Private subnets* - Runners not directly accessible from internet 5. *SSM for access* - No SSH keys needed 6. *Encrypted secrets* - Secrets Manager encryption at rest 7. *CloudWatch logging* - All runner activity logged ## References - [GitHub Self-hosted Runners Documentation](https://docs.github.com/en/actions/hosting-your-own-runners/...) - [GitHub Runner Registration API](https://docs.github.com/en/rest/actions/self-hosted-runners) - [AWS Auto Scaling Documentation](https://docs.aws.amazon.com/autoscaling/ec2/userguide/what-i...) - [AWS CodeBuild API Reference](https://docs.aws.amazon.com/codebuild/latest/APIReference/We...) - [GitHub Actions Runner Releases](https://github.com/actions/runner/releases) - [AWS Systems Manager Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide...) This solution provides a production-ready, cost-effective EC2-based runner infrastructure with automatic scaling, comprehensive monitoring, and multi-repository support for triggering CodeBuild pipelines.
In Ask HN: Do you have any evidence that agentic coding works?
At work we have a bunch of GitHub actions for integration testing, building models, publishing, reporting, and whatnot. It was horrible to maintain and look into whenever something went wrong, so I rewrote all the individual parts in Perl and hooked them together with pipes inside GHA, and it works wonders. Also, GitHub actions itself just breaks sometimes, which is super annoying. A couple of weeks ago, half of all the macOS runner images broke when using GitHub's caching system. Seems like that would have been caught on GitHub's side before that happened, but what do I know! > https://github.com/actions/runner/issues/449 > https://github.com/orgs/community/discussions/180160
In I hate GitHub Actions with passion
I wonder how much they made from engineering practices such as https://github.com/actions/runner/issues/3792. To spell it out: jobs can hang forever because of some ridiculously bad code on their end, they have a 6 hour cap, so that's 6 hours of billable $$$ per-instance of the bug (assuming it wasn't manually canceled). I know I've seen jobs hang forever regularly over the course of my years using GitHub for work. Note: pretty sure this has been resolved.
In Pricing Changes for GitHub Actions

Showing the 15 most recent of 61 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.