From 549fe6eb1eea3f724950bbe1c65707fd04a89faa Mon Sep 17 00:00:00 2001 From: zuchka Date: Thu, 7 May 2026 19:21:23 -0700 Subject: [PATCH] remove: drop all CircleCI support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes CircleCI from DING entirely: - internal/runctx/runctx.go: drop the CIRCLECI=true detection case; removes `circleci` from the package-doc runner list - internal/runctx/runctx_test.go: drop TestNew_DetectsCircleCI; remove CIRCLE_* env vars from clearCIEnv - docs/recipes/circleci.md: deleted - docs/recipes/index.md: drop CircleCI status row - mkdocs.yml: drop CircleCI nav entry - README.md: drop CircleCI from auto-detection runner table and the CI/CD recipes list - docs/configuration.md: drop CircleCI from "Platform-specific examples" pointer - docs/recipes/jenkins.md: drop "/ CircleCI" reference in a Tradeoffs bullet This is a breaking change for any existing user with rules that match `runner=circleci` or use CircleCI-derived run-context labels — those alerts will now report `runner=local` instead. Background: an attempted Tier-2 CircleCI orb hit unrecoverable CCI auth/onboarding friction for new GitHub orgs. Rather than ship a half-supported integration, removing CircleCI entirely until the DevOps story improves. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 3 +- docs/configuration.md | 2 +- docs/recipes/circleci.md | 101 --------------------------------- docs/recipes/index.md | 1 - docs/recipes/jenkins.md | 2 +- internal/runctx/runctx.go | 9 +-- internal/runctx/runctx_test.go | 17 ------ mkdocs.yml | 1 - 8 files changed, 4 insertions(+), 132 deletions(-) delete mode 100644 docs/recipes/circleci.md diff --git a/README.md b/README.md index c0c61a4..ec8b36f 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,6 @@ DING reads the runner's environment variables and attaches labels automatically. |---|---|---| | GitHub Actions | `GITHUB_ACTIONS=true` | `run_id`, `runner`, `repo`, `branch`, `commit`, `workflow`, `job`, `actor`, `event` | | GitLab CI | `GITLAB_CI=true` | `run_id`, `runner`, `repo`, `branch`, `commit`, `job` | -| CircleCI | `CIRCLECI=true` | `run_id`, `runner`, `repo`, `branch`, `commit`, `job` | | Jenkins | `JENKINS_URL` set | `run_id`, `runner`, `job`, `build` | | Buildkite | `BUILDKITE=true` | `run_id`, `runner`, `repo`, `branch`, `commit` | | Argo Workflows | `ARGO_TEMPLATE` set | `run_id`, `runner`, `workflow`, `node`, `pod`, `namespace` | @@ -266,7 +265,7 @@ The webhook receives a JSON POST: Looking for a config that works on your specific platform? See **[docs/recipes/](docs/recipes/index.md)** for platform-specific guides: -- **CI/CD:** [GitHub Actions](https://github.com/ding-labs/ding-action) · [GitLab CI](docs/recipes/gitlab-ci.md) · [CircleCI](docs/recipes/circleci.md) · [Jenkins](docs/recipes/jenkins.md) · [Buildkite](docs/recipes/buildkite.md) +- **CI/CD:** [GitHub Actions](https://github.com/ding-labs/ding-action) · [GitLab CI](docs/recipes/gitlab-ci.md) · [Jenkins](docs/recipes/jenkins.md) · [Buildkite](docs/recipes/buildkite.md) - **Orchestration:** [Kubernetes Jobs / CronJobs](docs/recipes/kubernetes-jobs.md) · [Argo Workflows](docs/recipes/argo-workflows.md) - **ML:** [MLflow](docs/recipes/mlflow.md) · [Ray Train / Tune](docs/recipes/ray.md) · [Modal](docs/recipes/modal.md) - More platforms (dbt, RunPod, Replicate, Airflow, …) coming in subsequent waves. diff --git a/docs/configuration.md b/docs/configuration.md index 5e72c33..1459f0c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -392,4 +392,4 @@ For typical secrets (Slack URLs, PagerDuty tokens, API keys, opaque ID strings) ## Platform-specific examples -See [Recipes](recipes/index.md) for end-to-end configurations on specific CI/CD platforms (GitLab CI, CircleCI, Jenkins, Buildkite). Each recipe shows the auto-captured labels and the minimal `ding.yaml` for that platform. +See [Recipes](recipes/index.md) for end-to-end configurations on specific CI/CD platforms (GitLab CI, Jenkins, Buildkite). Each recipe shows the auto-captured labels and the minimal `ding.yaml` for that platform. diff --git a/docs/recipes/circleci.md b/docs/recipes/circleci.md deleted file mode 100644 index 89a101c..0000000 --- a/docs/recipes/circleci.md +++ /dev/null @@ -1,101 +0,0 @@ -# Using DING with CircleCI - -> CircleCI is a hosted CI/CD platform built around YAML-defined workflows. DING's `ding run` wraps a job step, evaluates rules, and fires alerts on exit — leveraging CircleCI's environment to auto-tag every alert with project, branch, and commit context. - -## Prerequisites - -- DING binary `>= v0.3.0` — see [install](../install.md) -- A CircleCI project (free tier covers most personal/OSS use) -- A notifier endpoint (Slack webhook URL, custom webhook, etc.) - -## Minimal example - -`.circleci/config.yml`: - -```yaml -version: 2.1 - -jobs: - test: - docker: - - image: cimg/base:current - steps: - - checkout - - run: - name: Install DING - command: | - curl -sSL https://github.com/ding-labs/ding/releases/latest/download/ding_linux_amd64.tar.gz | tar -xz - - run: - name: Run tests with DING - command: ./ding run --config ding.yaml -- ./run-tests.sh - -workflows: - test_workflow: - jobs: - - test -``` - -`ding.yaml`: - -```yaml -notifiers: - slack: - type: slack - url: ${SLACK_WEBHOOK_URL} - -rules: - - name: ci_job_failed - match: - metric: run.exit - condition: value > 0 - message: "{{ .repo }}@{{ .branch }} failed (exit {{ .exit_code }})" - alert: - - notifier: slack -``` - -Set `SLACK_WEBHOOK_URL` as an [environment variable](https://circleci.com/docs/env-vars/) in your CircleCI project settings. - -## What you get - -A Slack message when the job exits non-zero, automatically tagged with `repo`, `branch`, `commit`, `job` from CircleCI's environment. Successful runs produce no notification. - -## Configuration - -`runctx` auto-detects CircleCI via the `CIRCLECI=true` environment variable and captures these labels: - -| Label | CircleCI env var | -|---|---| -| `run_id` | `CIRCLE_BUILD_NUM` | -| `runner` | `"circleci"` (set by runctx) | -| `repo` | `CIRCLE_PROJECT_REPONAME` | -| `branch` | `CIRCLE_BRANCH` | -| `commit` | `CIRCLE_SHA1` | -| `job` | `CIRCLE_JOB` | - -Use these in `match.labels` or `message` templates. See [Configuration](../configuration.md) for the full notifier reference. - -## Verification - -1. Locally: `ding validate --config ding.yaml` — confirms the rule parses. -2. Push a commit. Confirm a successful job produces no alert. -3. Force a failure (`exit 1` in `run-tests.sh`). Confirm the alert fires in Slack within ~5 seconds of job exit. - -If the alert doesn't fire, check the CircleCI job log for `ding` output. Common issues: webhook URL not exposed to the job (project-level vs context-level variable scoping), or `drain_timeout` shorter than the notifier retry window — see [Configuration](../configuration.md). - -## Tradeoffs / known limitations - -- **No native annotation surface.** CircleCI doesn't have a step-summary equivalent to GitHub Actions' `$GITHUB_STEP_SUMMARY`. Alerts go to your notifier; CircleCI's UI shows DING's stdout. -- **Binary download per job.** Bake DING into a [custom Docker image](https://circleci.com/docs/custom-images/) for high-frequency workflows. -- **Orb not provided.** A CircleCI orb (a packaged config wrapper) would collapse the install step into one line — that's the most likely Tier-2 promotion target. -- **Recipe assumes `cimg/base:current` includes `curl` and `tar`** (currently true). If you switch to a minimal custom image, add explicit install steps. - -## Escalation criteria - -This recipe is **Tier 1** by the program's standard rubric: - -- **Setup commands required:** 1 (`curl | tar`) — under threshold of 5 -- **Boilerplate lines:** ~32 across `.circleci/config.yml` and `ding.yaml` — under threshold of 50 -- **"Gotcha" callouts:** 3 structural (no annotation surface, binary download per job, no orb) — over threshold of 2 → **Tier-2 candidate** -- **End-to-end runnable:** yes (CircleCI free tier sufficient for evaluation; minutes allotment varies — see [CircleCI pricing](https://circleci.com/pricing/)) - -**Tier-2 candidate.** Three callouts cross the rubric threshold. The natural Tier-2 abstraction is a CircleCI orb (`ding-labs/ding`) that exposes a `ding/run` step — collapsing the install + invoke pattern into one line. Defer until 2+ users ask for it (per spec §"Open Questions" promotion authority). diff --git a/docs/recipes/index.md b/docs/recipes/index.md index 9803247..d136de4 100644 --- a/docs/recipes/index.md +++ b/docs/recipes/index.md @@ -16,7 +16,6 @@ Recipes marked **Tier-2 candidate** in the table below have self-evaluated as ex |---|---|---|---| | [GitHub Actions](https://github.com/ding-labs/ding-action) | CI/CD | Tier 2 (separate repo) | shipped | | [GitLab CI](gitlab-ci.md) | CI/CD | Tier 1 | shipped | -| [CircleCI](circleci.md) | CI/CD | Tier 1 | shipped (Tier-2 candidate) | | [Jenkins](jenkins.md) | CI/CD | Tier 1 | shipped (Tier-2 candidate) | | [Buildkite](buildkite.md) | CI/CD | Tier 1 | shipped (Tier-2 candidate) | | [Kubernetes Jobs / CronJobs](kubernetes-jobs.md) | Orchestration | Tier 1 | shipped (Tier-2 candidate) | diff --git a/docs/recipes/jenkins.md b/docs/recipes/jenkins.md index 938d768..95124c8 100644 --- a/docs/recipes/jenkins.md +++ b/docs/recipes/jenkins.md @@ -81,7 +81,7 @@ If the alert doesn't fire, check the Jenkins build console for `ding` output. Co ## Tradeoffs / known limitations -- **No SCM-aware labels by default.** Unlike GitHub Actions / GitLab CI / CircleCI, Jenkins doesn't have a single `BRANCH` env var that works across all SCM plugins. You'll need to surface `GIT_BRANCH` / `GIT_COMMIT` (Git plugin) or equivalent yourself. +- **No SCM-aware labels by default.** Unlike GitHub Actions or GitLab CI, Jenkins doesn't have a single `BRANCH` env var that works across all SCM plugins. You'll need to surface `GIT_BRANCH` / `GIT_COMMIT` (Git plugin) or equivalent yourself. - **Binary download per job.** Cache DING in a Docker agent image, or as a [Tool Installation](https://www.jenkins.io/doc/book/managing/tools/) configuration on the controller. - **No native plugin (yet).** A Jenkins plugin would expose alerts in the build console UI alongside DING's stdout. That's the most likely Tier-2 abstraction. diff --git a/internal/runctx/runctx.go b/internal/runctx/runctx.go index d5dd549..bb87ed6 100644 --- a/internal/runctx/runctx.go +++ b/internal/runctx/runctx.go @@ -1,7 +1,7 @@ // Package runctx holds run/job-scoped metadata for `ding run` mode. // // A Context auto-detects the surrounding CI/job runner (GitHub Actions, -// GitLab CI, CircleCI, Jenkins, Buildkite, Argo Workflows, Ray, MLflow, Kubernetes) from environment variables and exposes +// GitLab CI, Jenkins, Buildkite, Argo Workflows, Ray, MLflow, Kubernetes) from environment variables and exposes // helpers that attach run-scoped labels to events flowing through the // alerting engine. On run exit, SummaryEvent produces a synthetic // "run.exit" event with the exit code and run duration so rules can @@ -69,13 +69,6 @@ func (c *Context) detect() { setIf(c.Labels, "branch", os.Getenv("CI_COMMIT_REF_NAME")) setIf(c.Labels, "commit", os.Getenv("CI_COMMIT_SHA")) setIf(c.Labels, "job", os.Getenv("CI_JOB_NAME")) - case os.Getenv("CIRCLECI") == "true": - c.Runner = "circleci" - c.RunID = os.Getenv("CIRCLE_BUILD_NUM") - setIf(c.Labels, "repo", os.Getenv("CIRCLE_PROJECT_REPONAME")) - setIf(c.Labels, "branch", os.Getenv("CIRCLE_BRANCH")) - setIf(c.Labels, "commit", os.Getenv("CIRCLE_SHA1")) - setIf(c.Labels, "job", os.Getenv("CIRCLE_JOB")) case os.Getenv("JENKINS_URL") != "": c.Runner = "jenkins" c.RunID = os.Getenv("BUILD_TAG") diff --git a/internal/runctx/runctx_test.go b/internal/runctx/runctx_test.go index 8222bd0..4f82215 100644 --- a/internal/runctx/runctx_test.go +++ b/internal/runctx/runctx_test.go @@ -70,21 +70,6 @@ func TestNew_DetectsGitLabCI(t *testing.T) { } } -func TestNew_DetectsCircleCI(t *testing.T) { - clearCIEnv(t) - t.Setenv("CIRCLECI", "true") - t.Setenv("CIRCLE_BUILD_NUM", "7") - t.Setenv("CIRCLE_BRANCH", "main") - - c := New() - if c.Runner != "circleci" { - t.Errorf("Runner = %q, want circleci", c.Runner) - } - if c.RunID != "7" { - t.Errorf("RunID = %q, want 7", c.RunID) - } -} - func TestNew_DetectsJenkins(t *testing.T) { clearCIEnv(t) t.Setenv("JENKINS_URL", "http://jenkins.local") @@ -583,8 +568,6 @@ func clearCIEnv(t *testing.T) { "GITHUB_SHA", "GITHUB_WORKFLOW", "GITHUB_JOB", "GITHUB_ACTOR", "GITHUB_EVENT_NAME", "GITLAB_CI", "CI_PIPELINE_ID", "CI_PROJECT_PATH", "CI_COMMIT_REF_NAME", "CI_COMMIT_SHA", "CI_JOB_NAME", - "CIRCLECI", "CIRCLE_BUILD_NUM", "CIRCLE_PROJECT_REPONAME", "CIRCLE_BRANCH", - "CIRCLE_SHA1", "CIRCLE_JOB", "JENKINS_URL", "BUILD_TAG", "JOB_NAME", "BUILD_NUMBER", "BUILDKITE", "BUILDKITE_BUILD_ID", "BUILDKITE_PIPELINE_SLUG", "BUILDKITE_BRANCH", "BUILDKITE_COMMIT", diff --git a/mkdocs.yml b/mkdocs.yml index 350a7aa..a6d27b1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -33,7 +33,6 @@ nav: - Recipes: - Overview: recipes/index.md - GitLab CI: recipes/gitlab-ci.md - - CircleCI: recipes/circleci.md - Jenkins: recipes/jenkins.md - Buildkite: recipes/buildkite.md - Kubernetes Jobs: recipes/kubernetes-jobs.md