ワンクリックで
gitlab
GitLab REST API and git workflows on gitlab.home.shdr.ch — search projects, clone, branch, push, open/update MRs, check pipelines.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
GitLab REST API and git workflows on gitlab.home.shdr.ch — search projects, clone, branch, push, open/update MRs, check pipelines.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Interactively investigate Aether outages, alerts, regressions, performance issues, failed deployments, missing telemetry, backup failures, authentication problems, and network/security questions using live read-only evidence, including human follow-up on an Inquest incident. Use Grafana as the primary correlation surface across Prometheus metrics, Loki logs, Tempo traces, ClickHouse Zeek/Suricata data, Kubernetes state, Fleet, Talos, SSH, and service APIs. This is not the unattended Grafana-to-Kestra-to-Holmes-to-GitLab pipeline owned by sibling ../inquest; consume its incident record when present, independently verify its RCA, and stop before remediation or live mutation.
Map an Aether component, service, host, or proposed change to its runtime, placement, authoritative IaC, configuration owner, Taskfile workflow, dependencies, observability, and current documentation. Use for architecture questions, locating source files, determining whether something runs in Kubernetes or on a VM/LXC/host/cloud, planning where a change belongs, onboarding to the repo, and resolving conflicts between docs and code. For Inquest, separate the sibling repo's automated alert flows and incident lifecycle from Aether's Kestra, Holmes, Grafana, secret, and network platform ownership. This skill orients; use investigate-aether for live incident evidence.
| name | gitlab |
| description | GitLab REST API and git workflows on gitlab.home.shdr.ch — search projects, clone, branch, push, open/update MRs, check pipelines. |
| version | 1.0.0 |
| author | aether |
| license | MIT |
| platforms | ["linux"] |
| metadata | {"hermes":{"tags":["GitLab","Merge-Requests","Git","CI/CD","API"],"related_skills":[],"requires_toolsets":["terminal"]}} |
Use GitLab REST API via curl and git over HTTPS. Do not use browser
automation for GitLab tasks.
Adapted from vm0-ai/vm0-skills/gitlab
for Hermes + gitlab.home.shdr.ch.
Already injected by IaC (never print token values):
GITLAB_URL — https://gitlab.home.shdr.chGITLAB_HOST — gitlab.home.shdr.chGITLAB_TOKEN — bot PAT (read_api, read_repository, write_repository)API base: "${GITLAB_URL}/api/v4"
Auth header: PRIVATE-TOKEN: ${GITLAB_TOKEN}
Reload token in shell if missing:
if [ -z "${GITLAB_TOKEN:-}" ] && [ -f "${HERMES_HOME:-$HOME}/.env" ]; then
GITLAB_TOKEN=$(grep '^GITLAB_TOKEN=' "${HERMES_HOME:-$HOME}/.env" | head -1 | cut -d= -f2- | tr -d '\n\r')
export GITLAB_TOKEN
fi
export GITLAB_URL="${GITLAB_URL:-https://gitlab.home.shdr.ch}"
export GITLAB_HOST="${GITLAB_HOST:-gitlab.home.shdr.ch}"
urlencode() { python3 -c 'import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1], safe=""))' "$1"; }
gitlab_json() {
curl -fsS -H "PRIVATE-TOKEN: ${GITLAB_TOKEN}" "$@"
}
When a command pipes curl to Python, wrap curl in bash -c '...' so env vars
survive the pipe.
gitlab_json "${GITLAB_URL}/api/v4/user" \
| python3 -c "import sys,json; u=json.load(sys.stdin); print(u['username'], u['id'])"
# By name (membership only)
curl -fsS -G -H "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
--data-urlencode "search=aether" \
--data-urlencode "membership=true" \
--data-urlencode "simple=true" \
"${GITLAB_URL}/api/v4/projects" \
| python3 -c "
import sys, json
for p in json.load(sys.stdin):
print(f\"{p['id']:>6} {p['path_with_namespace']} ({p['default_branch']})\")"
# Project details by path (primary IaC repo: so/aether)
PROJECT_PATH="so/aether"
gitlab_json "${GITLAB_URL}/api/v4/projects/$(urlencode "$PROJECT_PATH")" \
| python3 -c "import sys,json; p=json.load(sys.stdin); print(p['id'], p['web_url'], p['default_branch'])"
Default clone root: /workspace (terminal cwd).
PROJECT_PATH="so/aether"
TARGET="/workspace/aether"
mkdir -p /workspace
git clone "https://oauth2:${GITLAB_TOKEN}@${GITLAB_HOST}/${PROJECT_PATH}.git" "$TARGET"
cd "$TARGET"
git fetch origin
Set remote if already cloned without token:
git remote set-url origin "https://oauth2:${GITLAB_TOKEN}@${GITLAB_HOST}/so/aether.git"
main unless Shdrch says otherwise.main or master.feat/…, fix/…, docs/…, ci/….cd /workspace/aether
git fetch origin
git checkout main && git pull origin main
git checkout -b feat/short-description
# edit files with write_file / patch
git add -A
git commit -m "feat: short description"
git push -u origin HEAD
export BRANCH=$(git branch --show-current)
PROJECT_PATH=$(git remote get-url origin | sed -E "s|.*${GITLAB_HOST}[:/]||; s|\\.git$||")
PROJECT_ID=$(gitlab_json "${GITLAB_URL}/api/v4/projects/$(urlencode "$PROJECT_PATH")" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
PROJECT_PATH="so/aether"
curl -fsS -G -H "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
--data-urlencode "state=opened" \
"${GITLAB_URL}/api/v4/projects/$(urlencode "$PROJECT_PATH")/merge_requests" \
| python3 -c "
import sys, json
for mr in json.load(sys.stdin):
print(f\"!{mr['iid']} {mr['title']} {mr['source_branch']} -> {mr['target_branch']} {mr['web_url']}\")"
After push:
curl -fsS -X POST -H "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
-H "Content-Type: application/json" \
"${GITLAB_URL}/api/v4/projects/${PROJECT_ID}/merge_requests" \
-d "$(python3 - <<PY
import json, os
print(json.dumps({
"source_branch": os.environ["BRANCH"],
"target_branch": "main",
"title": "feat: short description",
"description": "## Summary\\n- change\\n\\n## Test plan\\n- [ ] task tofu:plan",
"remove_source_branch": True,
}))
PY
)" | python3 -c "import sys,json; mr=json.load(sys.stdin); print(mr['web_url'])"
Reply to Shdrch with the MR URL. Reuse the same branch/MR for follow-up commits.
MR_IID=42
curl -fsS -X PUT -H "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
-H "Content-Type: application/json" \
"${GITLAB_URL}/api/v4/projects/${PROJECT_ID}/merge_requests/${MR_IID}" \
-d '{"title":"feat: updated title","description":"## Summary\\nUpdated"}'
MR_IID=42
gitlab_json "${GITLAB_URL}/api/v4/projects/${PROJECT_ID}/merge_requests/${MR_IID}/pipelines" \
| python3 -c "
import sys, json
for p in json.load(sys.stdin):
print(p['id'], p['status'], p.get('web_url',''))"
GET/POST MR create over destructive API calls.