{"id":23104072,"url":"https://github.com/glueops/pull-request-bot","last_synced_at":"2026-04-02T15:06:18.151Z","repository":{"id":107190974,"uuid":"598314255","full_name":"GlueOps/pull-request-bot","owner":"GlueOps","description":"This repository contains a Pull Request bot that monitors ArgoCD applications in a Kubernetes cluster. It automatically adds comments to pull requests with deployment preview URLs, metrics, logs, and QR codes. The bot integrates with GitHub APIs and ArgoCD to provide real-time deployment feedback.","archived":false,"fork":false,"pushed_at":"2026-02-13T00:17:15.000Z","size":146,"stargazers_count":2,"open_issues_count":6,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-02-13T10:20:53.719Z","etag":null,"topics":["allow-auto-merge","argocd","argocd-automation","bot","deployment-feedback","deployment-preview","docker","ephemeral-environments","github","github-integration","glueops-platform","kubernetes","monitoring","preview","preview-environment","pull-request-bot","pull-requests","qr-code"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GlueOps.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-02-06T21:09:37.000Z","updated_at":"2026-02-12T08:54:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"e9c41cbd-64ec-4f3e-a351-a74abeac6971","html_url":"https://github.com/GlueOps/pull-request-bot","commit_stats":null,"previous_names":[],"tags_count":63,"template":false,"template_full_name":null,"purl":"pkg:github/GlueOps/pull-request-bot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GlueOps%2Fpull-request-bot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GlueOps%2Fpull-request-bot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GlueOps%2Fpull-request-bot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GlueOps%2Fpull-request-bot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GlueOps","download_url":"https://codeload.github.com/GlueOps/pull-request-bot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GlueOps%2Fpull-request-bot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29554506,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-17T18:16:07.221Z","status":"ssl_error","status_checked_at":"2026-02-17T18:16:04.782Z","response_time":100,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["allow-auto-merge","argocd","argocd-automation","bot","deployment-feedback","deployment-preview","docker","ephemeral-environments","github","github-integration","glueops-platform","kubernetes","monitoring","preview","preview-environment","pull-request-bot","pull-requests","qr-code"],"created_at":"2024-12-17T00:31:10.933Z","updated_at":"2026-04-02T15:06:18.141Z","avatar_url":"https://github.com/GlueOps.png","language":"Python","readme":"# Preview Environment PR Commenter (Go)\n\nA small Kubernetes service that watches **Argo CD Applications** representing preview environments and posts a **GitHub Pull Request comment** with:\n\n- the latest commit SHA deployed,\n- an Argo CD link,\n- preview links rendered as **QR codes** (minted via a protected QR signing service),\n- Grafana metrics and Loki logs links.\n\nIt’s designed for GitOps/preview workflows where each PR spins up a temporary environment and you want an automatic “here’s where it is” comment.\n\n---\n\n## How it works\n\nOn a fixed interval, the service:\n\n1. Lists Argo CD `Applications` (`argoproj.io/v1alpha1`) from Kubernetes using the dynamic client.\n2. Filters to apps that:\n    - have at least one `ownerReference`,\n    - have annotation `preview_environment: \"true\"`,\n    - have annotation `head_sha` and the SHA appears in `status.sync.revisions`,\n    - have `status.health.status` of `Healthy` or `Degraded`,\n    - have at least one `status.summary.externalURLs` entry,\n    - contain required GitHub metadata annotations: `repository_organization`, `repository_name`, `pull_request_number`.\n3. Builds links to:\n    - Argo CD application page,\n    - Grafana “workload metrics” dashboard,\n    - Loki logs dashboard.\n4. For each external URL, calls a QR mint endpoint to produce a signed QR image URL.\n5. Posts a markdown table comment to the matching PR via the GitHub API.\n6. De-duplicates per process lifetime using `head_sha` (in-memory).\n\n---\n\n## Inputs expected on the Argo CD Application\n\n### Required annotations\n\n| Annotation | Required | Meaning |\n|---|:---:|---|\n| `preview_environment` | ✅ | Must be `\"true\"` to be considered |\n| `head_sha` | ✅ | Commit SHA expected to be deployed |\n| `repository_organization` | ✅ | GitHub org/owner |\n| `repository_name` | ✅ | GitHub repo name |\n| `pull_request_number` | ✅ | PR number to comment on |\n\n### Required status fields (set by Argo CD)\n\n- `status.sync.revisions` must contain `head_sha`\n- `status.health.status` must be `Healthy` or `Degraded`\n- `status.summary.externalURLs` must contain at least one URL\n\n---\n\n## Configuration\n\nConfiguration is via environment variables:\n\n| Env var | Default | Required | Description |\n|---|---:|:---:|---|\n| `NAMESPACE` | `glueops-core` |  | Namespace used to read ConfigMap/Secret and list Applications |\n| `GITHUB_APP_SECRET_NAME` | `tenant-repo-creds` |  | K8s Secret with GitHub App credentials |\n| `CAPTAIN_DOMAIN_K8S_CONFIGMAP_NAME` | `glueops-captain-domain` |  | K8s ConfigMap with `captain_domain` |\n| `WATCH_FOR_APPS_DELAY_SECONDS` | `10` |  | Poll interval in seconds |\n| `QR_MINT_TOKEN` |  | ✅ | Bearer token for QR signing endpoint |\n| `QR_TTL_SECONDS` | `600` |  | Signed QR TTL in seconds |\n| `KUBECONFIG` | `~/.kube/config` |  | Used only when not running in-cluster |\n\nHard-coded defaults:\n- HTTP timeout: 15 seconds\n- GitHub API version header: `2022-11-28`\n\n---\n\n## Kubernetes resources required\n\n### ConfigMap: captain domain\n\nA ConfigMap containing the base domain used for service links:\n\n- Name: `CAPTAIN_DOMAIN_K8S_CONFIGMAP_NAME` (default `glueops-captain-domain`)\n- Key: `captain_domain`\n\nExample:\n\n```yaml\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: glueops-captain-domain\n  namespace: glueops-core\ndata:\n  captain_domain: example.internal\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglueops%2Fpull-request-bot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fglueops%2Fpull-request-bot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglueops%2Fpull-request-bot/lists"}