Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Tutorial Qa To Prod

ASecurity

Use when a tutorial author has previewed a tutorial in the QA channel (/tutorials-qa/) and wants to promote it to PROD — copies the tutorial markdown from the private sap-tutorials/<product>-Contribution repo (QA source) to the canonical public sap-tutorials/Tutorials repo (PROD source) and opens a PR in each, cross-linked. Triggers on "promote this tutorial to prod", "copy from QA to PROD", "publish my QA tutorial", "move <slug> from Contribution to Tutorials".

12 stars
0 votes
0 copies
0 views
Added 9/20/2026
developmentgobashrailsgitapi

Works with

api

Security Analysis

A100/100

Scanned 9/20/2026

Install to Claude Code

$npx -y skills add sap-tutorials/tutorials-ims --skill tutorial-qa-to-prod --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Tutorial Qa To Prod?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Tutorial Qa To Prod
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/sap-tutorials-tutorial-qa-to-prod/badge)](https://www.skillsdirectory.com/skills/sap-tutorials-tutorial-qa-to-prod)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: tutorial-qa-to-prod
description: Use when a tutorial author has previewed a tutorial in the QA channel (/tutorials-qa/) and wants to promote it to PROD — copies the tutorial markdown from the private sap-tutorials/<product>-Contribution repo (QA source) to the canonical public sap-tutorials/Tutorials repo (PROD source) and opens a PR in each, cross-linked. Triggers on "promote this tutorial to prod", "copy from QA to PROD", "publish my QA tutorial", "move <slug> from Contribution to Tutorials".
---

# Promote a tutorial from QA (Contribution) to PROD (canonical Tutorials)

An author edits and previews a tutorial in its product-specific
**`sap-tutorials/<product>-Contribution`** repo, served on the platform's QA
channel at `/tutorials-qa/<slug>`. Promoting it to PROD means landing the same
markdown in the **canonical public repo `sap-tutorials/Tutorials`** at the same
`tutorials/<slug>/<slug>.md` path. Merging the `Tutorials` PR is what the PROD
content rebuild consumes — the platform auto-discovers `Tutorials` content and
republishes to the PROD HANA BLOBs.

The two repos share **no git fork network**, so one cross-repo PR is impossible.
This skill copies the file once and opens **one PR in each repo**, cross-linked.

## Non-negotiable facts (verified 2026-09-15)

- **Host is `github.com`, NOT `github.tools.sap`.** Always `export GH_HOST=github.com`.
- **Default branches DIFFER per repo — never hardcode.**
  - Canonical `sap-tutorials/Tutorials` (PROD) → **`master`**.
  - `sap-tutorials/<product>-Contribution` (QA) → **`main`**.
  - Resolve each repo's default with the API (Step 0); do not assume.
- **`*-Contribution` repos are private** → `raw.githubusercontent.com` 404s.
  Verify pushed content via the authenticated contents API, not raw curl.
- **Path parity.** Both repos use `tutorials/<slug>/<slug>.md`. Same slug → same path.
- **First promotion is a CREATE, not an update.** A QA-only tutorial does NOT
  exist in `Tutorials` yet (contents API returns 404). Handle create vs update.
- **No `tutorials-ims` code change is needed.** The platform auto-discovers any
  org repo with a `tutorials/` folder; merging the `Tutorials` PR triggers PROD.

## Workflow

Work through the GitHub contents API (`gh api`) — do NOT clone `Tutorials`; it is
huge. Use `$CLAUDE_JOB_DIR/tmp` or a scratch dir for the file. Set
`export GH_HOST=github.com` first.

### Step 0 — Resolve inputs and per-repo default branches

Identify the QA repo (`sap-tutorials/<product>-Contribution`), the slug, and the
path `tutorials/<slug>/<slug>.md`. Then resolve BOTH default branches — do not
assume:

```bash
export GH_HOST=github.com
CONTRIB=sap-tutorials/<product>-Contribution
MAIN=sap-tutorials/Tutorials
PATHREL="tutorials/<slug>/<slug>.md"

CONTRIB_DEF=$(gh api "repos/$CONTRIB" --jq '.default_branch')   # expect: main
MAIN_DEF=$(gh api "repos/$MAIN"    --jq '.default_branch')      # expect: master
```

### Step 1 — Fetch the QA source (source of truth for the copy)

The QA file is what the author previewed and approved — it is authoritative.

```bash
CONTRIB_SHA=$(gh api "repos/$CONTRIB/contents/$PATHREL?ref=$CONTRIB_DEF" --jq '.sha')
gh api "repos/$CONTRIB/contents/$PATHREL?ref=$CONTRIB_DEF" --jq '.content' | base64 -d > file.md
```

If this 404s, the slug/path is wrong — re-confirm with the author. Do NOT invent content.

### Step 2 — Determine PROD state: CREATE or UPDATE (+ drift guard)

```bash
if MAIN_SHA=$(gh api "repos/$MAIN/contents/$PATHREL?ref=$MAIN_DEF" --jq '.sha' 2>/dev/null); then
  MODE=update
else
  MODE=create   # QA-only tutorial, first promotion — no sha, no drift check
fi
```

- **MODE=create** → nothing in PROD to clobber. Proceed; the contents PUT omits `sha`.
- **MODE=update** → PROD already has this tutorial. **DRIFT GUARD:** diff the
  current PROD file against the QA file you fetched. If PROD has content the QA
  copy would silently discard (someone edited PROD directly, or the repos have
  drifted), **STOP and show the author the diff** before overwriting:

  ```bash
  gh api "repos/$MAIN/contents/$PATHREL?ref=$MAIN_DEF" --jq '.content' | base64 -d > prod-current.md
  diff prod-current.md file.md && echo "IN SYNC (no-op)" || echo "DRIFT — review below before promoting"
  ```

  If `diff` is empty, the promotion is a no-op — tell the author PROD already
  matches QA; don't open an empty PR. If it differs, that's the expected
  promotion delta — but confirm the diff is only the author's intended change,
  not an unrelated PROD edit being reverted.

### Step 3 — For EACH repo, branch + commit the copied file

Same branch name in both (e.g. `promote/<slug>-to-prod`). QA repo commits the
same content back to itself on a branch (so the promotion is auditable there
too); PROD repo receives the copy. Use each repo's OWN default branch as base
and each repo's OWN current file sha.

```bash
promote_to() {   # $1=repo  $2=default-branch  $3=current-file-sha-or-empty
  local REPO="$1" DEF="$2" CUR_SHA="$3" BR="promote/<slug>-to-prod"
  local BASE_SHA; BASE_SHA=$(gh api "repos/$REPO/git/ref/heads/$DEF" --jq '.object.sha')
  gh api "repos/$REPO/git/refs" -f ref="refs/heads/$BR" -f sha="$BASE_SHA" >/dev/null

  local B64; B64=$(base64 -w0 file.md)
  if [ -n "$CUR_SHA" ]; then
    printf '{"message":"docs(%s): promote to PROD","branch":"%s","sha":"%s","content":"%s"}' \
      "<slug>" "$BR" "$CUR_SHA" "$B64" > payload.json
  else
    printf '{"message":"docs(%s): promote to PROD","branch":"%s","content":"%s"}' \
      "<slug>" "$BR" "$B64" > payload.json
  fi
  gh api -X PUT "repos/$REPO/contents/$PATHREL" --input payload.json --jq '.commit.sha'

  # verify byte-for-byte (works on private repos)
  gh api "repos/$REPO/contents/$PATHREL?ref=$BR" --jq '.content' | base64 -d > pushed.md
  diff file.md pushed.md && echo "MATCH ($REPO)" || { echo "MISMATCH ($REPO) — STOP"; return 1; }
}

promote_to "$CONTRIB" "$CONTRIB_DEF" "$CONTRIB_SHA"           # QA branch (audit)
promote_to "$MAIN"    "$MAIN_DEF"    "${MAIN_SHA:-}"          # PROD copy (empty sha => create)
```

Do not open a PR for a repo until its `promote_to` printed `MATCH`.

### Step 4 — Open a PR in each repo, cross-linked

```bash
# PROD first (the one that matters), base = its OWN default branch
PROD_PR=$(gh pr create --repo "$MAIN" --base "$MAIN_DEF" --head promote/<slug>-to-prod \
  --title "Promote <slug> to PROD" \
  --body "Promotes QA-previewed tutorial \`<slug>\` to PROD. Paired QA PR: <fill after>. Merging this triggers the PROD content rebuild." )

QA_PR=$(gh pr create --repo "$CONTRIB" --base "$CONTRIB_DEF" --head promote/<slug>-to-prod \
  --title "Promote <slug> to PROD (QA-side record)" \
  --body "QA-side record of promoting \`<slug>\`. Paired PROD PR: $PROD_PR" )

gh pr edit "$PROD_PR" --body "Promotes QA-previewed tutorial \`<slug>\` to PROD. Paired QA PR: $QA_PR. Merging this triggers the PROD content rebuild."
```

### Step 5 — Report

Report **both PR URLs**, whether it was a CREATE or UPDATE, and that content was
verified identical in both. Remind the author: **merging the `Tutorials` (PROD)
PR is what publishes to PROD** — the QA-side PR is an audit record.

## Guardrails

- **Never hardcode a base branch.** Resolve each repo's default (Step 0);
  `Tutorials`=`master`, `-Contribution`=`main` today, but always resolve live.
- **Never open one PR expecting it to span both repos** — always two.
- **UPDATE mode: run the drift guard before overwriting PROD.** An empty diff is
  a no-op (don't open a PR); a diff must be confirmed as only the intended change.
- **Before adding a follow-up commit to an existing PR branch, check PR state**
  (`gh pr view <n> --repo <r> --json state,mergedAt`). If MERGED/CLOSED, branch
  fresh and open a NEW PR — a PUT to a merged PR's branch SUCCEEDS but never
  reaches the default branch. Confirm changes landed by reading the file at the
  default-branch ref.
- **Never `git push`/force-push; never target a non-default base branch.**
- **QA is the source of truth for the copy** — the author previewed it there.
  Do not hand-edit content during promotion; if the content is wrong, fix it in
  the Contribution repo first (see `sap-tutorial-dual-pr` for editing flows),
  then promote.
- This skill promotes ONE tutorial (one slug) per run. For a batch, loop the
  slug and open one PR pair per slug, or ask the author to confirm a multi-slug
  scope explicitly.

## Relationship to `sap-tutorial-dual-pr`

`sap-tutorial-dual-pr` **edits** a tutorial and mirrors the edit to both repos in
lockstep (keeping QA and PROD identical after an edit). This skill **promotes** a
QA-previewed tutorial to PROD (the QA→PROD direction, create-or-update, with a
drift guard for the first-promotion 404 case). Use dual-pr to change content;
use this to ship a QA-approved tutorial to PROD.

Attribution

sap-tutorialssap-tutorials
View sourceMore from sap-tutorials →
SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

285172 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2222 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

10311 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →