From a86e5876ebe805e9d922bce6eefd988acb7243b0 Mon Sep 17 00:00:00 2001 From: Siddharth Agrawal Date: Tue, 18 Oct 2022 16:54:26 +0530 Subject: [PATCH] create the circleci plugin --- plugins/circleci/README.md | 23 +++++++++ plugins/circleci/circleci.plugin.zsh | 12 +++++ plugins/circleci/circleci_status.py | 71 ++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 plugins/circleci/README.md create mode 100644 plugins/circleci/circleci.plugin.zsh create mode 100644 plugins/circleci/circleci_status.py diff --git a/plugins/circleci/README.md b/plugins/circleci/README.md new file mode 100644 index 000000000..ad84c6bbf --- /dev/null +++ b/plugins/circleci/README.md @@ -0,0 +1,23 @@ +# CircleCi Plugin + +This plugin provides easy to use cli commands to query circle ci job statuses + +To use it, add `circleci` to the plugins array in your zshrc file: + +```zsh +plugins=(... circleci) +``` + +## Prerequisites +You need to have the `CIRCLECI_API_TOKEN` and `CIRCLECI_ORG_SLUG` as environment +variables before calling the `circleci_status` function
+You can learn how to add a circleci api token [here](https://circleci.com/docs/managing-api-tokens/)
+The org slug takes the format of `{vcs}/{org_name}` + +## Usage +```shell +> circleci_status +``` +The above command would list down all the jobs (with their run status) on the +repository and branch that you are currently on
+You can also use the `cis` alias to run the above function diff --git a/plugins/circleci/circleci.plugin.zsh b/plugins/circleci/circleci.plugin.zsh new file mode 100644 index 000000000..5cdcf8566 --- /dev/null +++ b/plugins/circleci/circleci.plugin.zsh @@ -0,0 +1,12 @@ +# Handle $0 according to the standard: +# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html +0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}" +0="${${(M)0:#/*}:-$PWD/$0}" +__CI_ZSH_DIR="${0:h:A}" + +alias cis='circleci_status' + + +function circleci_status() { + python3 "$__CI_ZSH_DIR"/circleci_status.py "$(git_current_branch)" "$(git_repo_name)" | less +} diff --git a/plugins/circleci/circleci_status.py b/plugins/circleci/circleci_status.py new file mode 100644 index 000000000..7e40944cf --- /dev/null +++ b/plugins/circleci/circleci_status.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 + +import requests +import os +import sys + +CIRCLECI_API = "https://circleci.com/api/v2" +org_slug = os.environ.get("CIRCLECI_ORG_SLUG") +args = sys.argv + + +class COLORS: + reset = '\033[0m' + + class FG: + red = '\033[31m' + green = '\033[32m' + yellow = '\033[93m' + + +def get_resp_items(resp): + if resp.status_code != 200: + sys.exit(0) + items = resp.json()["items"] + if len(items) == 0: + sys.exit(0) + return items + + +def get_status_text(status): + if status == "success": + return COLORS.FG.green + "✓" + COLORS.reset + elif status in ("running", "not_run", "retried", "queued"): + return COLORS.FG.yellow + "·" + COLORS.reset + else: + return COLORS.FG.red + "˟" + COLORS.reset + + +if not org_slug or len(args) != 3: + sys.exit(0) + +branch_name = args[1] +repo_name = args[2] + +# Here we query for all the pipelines belonging to the current branch in the current repo +headers = {"Circle-token": os.environ.get("CIRCLECI_API_TOKEN")} +url = f"{CIRCLECI_API}/project/{org_slug}/{repo_name}/pipeline" +params = {"branch": branch_name} +response = requests.get(url, headers=headers, params=params) +pipelines = get_resp_items(response) +# use the latest pipeline +pipeline_id = pipelines[0]["id"] + +# Now fetch the workflows for the selected pipeline +url = f"{CIRCLECI_API}/pipeline/{pipeline_id}/workflow" +response = requests.get(url, headers=headers) +workflows = get_resp_items(response) +# use the latest workflow +workflow_id = workflows[0]["id"] + +url = f"{CIRCLECI_API}/workflow/{workflow_id}/job" +response = requests.get(url, headers=headers) +jobs = get_resp_items(response) + +for job in jobs: + status = job["status"] + name = job["name"] + project_slug = job["project_slug"] + job_number = job["job_number"] + url = f"https://circleci.com/{project_slug}/{job_number}" + print("{} {:<50} {}".format(get_status_text(status), name, url))