Skills bitbucket
git clone https://github.com/TerminalSkills/skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/TerminalSkills/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/bitbucket" ~/.claude/skills/terminalskills-skills-bitbucket && rm -rf "$T"
skills/bitbucket/SKILL.md- references .env files
- references AWS credentials
Bitbucket
Overview
Automate and extend Bitbucket Cloud — Atlassian's Git platform with built-in CI/CD. This skill covers repository management, Bitbucket Pipelines configuration, pull request workflows, branch permissions, deployment environments, the REST API 2.0, webhooks, Jira integration, and merge checks.
Instructions
Step 1: Authentication
// Bitbucket Cloud uses App Passwords (basic auth) or OAuth 2.0. // Create an App Password at: https://bitbucket.org/account/settings/app-passwords/ const BB_BASE = "https://api.bitbucket.org/2.0"; const AUTH = Buffer.from( `${process.env.BB_USERNAME}:${process.env.BB_APP_PASSWORD}` ).toString("base64"); async function bb(method: string, path: string, body?: any) { const res = await fetch(`${BB_BASE}${path}`, { method, headers: { Authorization: `Basic ${AUTH}`, "Content-Type": "application/json", }, body: body ? JSON.stringify(body) : undefined, }); if (!res.ok) throw new Error(`BB ${method} ${path}: ${res.status} ${await res.text()}`); return res.status === 204 ? null : res.json(); }
Step 2: Repositories
// Create a repository const repo = await bb("POST", `/repositories/my-workspace/my-new-repo`, { scm: "git", is_private: true, description: "Backend API service", project: { key: "ENG" }, mainbranch: { name: "main" }, fork_policy: "no_public_forks", }); // List, get details, list branches const repos = await bb("GET", `/repositories/my-workspace?q=project.key="ENG"&sort=-updated_on&pagelen=25`); const repoInfo = await bb("GET", `/repositories/my-workspace/my-repo`); const branches = await bb("GET", `/repositories/my-workspace/my-repo/refs/branches?sort=-target.date&pagelen=25`); // Get file content / browse tree const fileContent = await fetch( `${BB_BASE}/repositories/my-workspace/my-repo/src/main/README.md`, { headers: { Authorization: `Basic ${AUTH}` } } ).then(r => r.text());
Step 3: Pull Requests
// Create a pull request (Jira keys like ENG-142 in description auto-link) const pr = await bb("POST", `/repositories/my-workspace/my-repo/pullrequests`, { title: "feat: add user authentication module", description: "Implements OAuth2 login.\n\nCloses ENG-142", source: { branch: { name: "feature/auth" } }, destination: { branch: { name: "main" } }, close_source_branch: true, reviewers: [{ account_id: "5f1234abc..." }], }); // List, approve, request changes const openPRs = await bb("GET", `/repositories/my-workspace/my-repo/pullrequests?state=OPEN&pagelen=50`); await bb("POST", `/repositories/my-workspace/my-repo/pullrequests/${pr.id}/approve`); await bb("POST", `/repositories/my-workspace/my-repo/pullrequests/${pr.id}/request-changes`); // Comments (general and inline on a specific file/line) await bb("POST", `/repositories/my-workspace/my-repo/pullrequests/${pr.id}/comments`, { content: { raw: "Looks good! One suggestion on the token expiry logic." }, }); await bb("POST", `/repositories/my-workspace/my-repo/pullrequests/${pr.id}/comments`, { content: { raw: "Use `crypto.timingSafeEqual` here to prevent timing attacks." }, inline: { path: "src/auth/jwt.ts", to: 42 }, }); // Merge: "merge_commit" | "squash" | "fast_forward" await bb("POST", `/repositories/my-workspace/my-repo/pullrequests/${pr.id}/merge`, { merge_strategy: "squash", message: "feat: add user authentication module (#142)", close_source_branch: true, });
Step 4: Branch Permissions & Merge Checks
// Branch permissions require Premium plan. Pattern supports globs: release/* // Require 2 approvals to merge to main await bb("POST", `/repositories/my-workspace/my-repo/branch-restrictions`, { kind: "require_approvals_to_merge", pattern: "main", value: 2, }); // Prevent direct pushes (force PRs) await bb("POST", `/repositories/my-workspace/my-repo/branch-restrictions`, { kind: "push", pattern: "main", users: [], groups: [], }); // Require passing builds and resolved tasks before merge await bb("POST", `/repositories/my-workspace/my-repo/branch-restrictions`, { kind: "require_passing_builds_to_merge", pattern: "main", value: 1, }); await bb("POST", `/repositories/my-workspace/my-repo/branch-restrictions`, { kind: "require_tasks_to_be_completed", pattern: "main", });
Step 5: Bitbucket Pipelines (CI/CD)
# bitbucket-pipelines.yml — runs in Docker containers image: node:20-slim definitions: steps: - step: &test name: Test caches: [node] script: [npm ci, npm run lint, npm run test:coverage] artifacts: [coverage/**] - step: &build name: Build caches: [node] script: [npm ci, npm run build] artifacts: [dist/**] pipelines: default: - step: *test branches: main: - step: *test - step: *build - step: name: Deploy to Production deployment: production trigger: manual script: - pipe: atlassian/aws-ecs-deploy:1.0.0 variables: AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY AWS_DEFAULT_REGION: "eu-west-1" CLUSTER_NAME: "prod-cluster" SERVICE_NAME: "api-service" pull-requests: '**': - step: *test custom: run-migrations: - step: name: Run Database Migrations script: [npm ci, npm run db:migrate]
// Trigger a custom pipeline via API const pipeline = await bb("POST", `/repositories/my-workspace/my-repo/pipelines/`, { target: { type: "pipeline_ref_target", ref_type: "branch", ref_name: "main", selector: { type: "custom", pattern: "run-migrations" }, }, variables: [{ key: "MIGRATION_TARGET", value: "v2.1.0", secured: false }], }); // Check status: state.name = "PENDING" | "IN_PROGRESS" | "COMPLETED" const status = await bb("GET", `/repositories/my-workspace/my-repo/pipelines/${pipeline.uuid}`); const pipelines = await bb("GET", `/repositories/my-workspace/my-repo/pipelines/?sort=-created_on&pagelen=10`);
Step 6: Deployment Environments & Variables
// Create environment: type name = "Test" | "Staging" | "Production" const environment = await bb("POST", `/repositories/my-workspace/my-repo/environments/`, { type: "deployment_environment", name: "Production", environment_type: { type: "deployment_environment_type", name: "Production" }, }); // Pipeline variables (secured=true encrypts, never shown in logs) await bb("POST", `/repositories/my-workspace/my-repo/pipelines_config/variables/`, { key: "AWS_ACCESS_KEY_ID", value: "AKIA...", secured: true, }); // Per-environment variables await bb("POST", `/repositories/my-workspace/my-repo/deployments_config/environments/${environment.uuid}/variables`, { key: "API_URL", value: "https://api.production.example.com", secured: false, });
Step 7: Webhooks & Jira Integration
// Register a webhook const webhook = await bb("POST", `/repositories/my-workspace/my-repo/hooks`, { description: "CI/CD event handler", url: "https://your-app.com/webhook/bitbucket", active: true, events: ["repo:push", "pullrequest:created", "pullrequest:fulfilled"], }); // Webhook handler — event type is in x-event-key header app.post("/webhook/bitbucket", (req, res) => { res.sendStatus(200); const event = req.headers["x-event-key"]; if (event === "repo:push") console.log(`Push to ${req.body.push.changes[0].new.name}`); if (event === "pullrequest:fulfilled") console.log(`PR merged: ${req.body.pullrequest.title}`); }); // Jira integration: mention keys (ENG-142) in commits/branches/PRs for auto-linking. // Smart commits: git commit -m "ENG-142 #time 2h #comment Fixed auth bug #done"
Step 8: Code Search & Reports
// Search code across workspace repositories const searchResults = await bb("GET", `/workspaces/my-workspace/search/code?search_query=${encodeURIComponent('lang:typescript "jwt.verify"')}&pagelen=20` ); // Commit history, diff, and branch comparison const commits = await bb("GET", `/repositories/my-workspace/my-repo/commits?pagelen=30`); const diff = await fetch(`${BB_BASE}/repositories/my-workspace/my-repo/diff/${commitHash}`, { headers: { Authorization: `Basic ${AUTH}` } }).then(r => r.text()); const compare = await bb("GET", `/repositories/my-workspace/my-repo/commits?include=main&exclude=release/2.0`);
Examples
Example 1: Set up a new repository with CI/CD and branch protection
User prompt: "Create a new private Bitbucket repository called 'payment-service' in the FINTECH workspace under the PAYMENTS project. Set up a CI pipeline that runs tests on every push, deploys to staging on develop, and requires manual approval for production deploys from main. Protect main with 2 required approvals."
The agent will:
- Create the repository via
withPOST /repositories/fintech-workspace/payment-service
andis_private: true
.project: { key: "PAYMENTS" } - Generate a
with test, build, staging deploy, and manual production deploy steps using YAML anchors for reusable step definitions.bitbucket-pipelines.yml - Add branch restrictions for
: require 2 approvals to merge, block direct pushes, and require passing builds.main - Set up deployment environments for Staging and Production with appropriate environment variables.
Example 2: Automate PR workflow with Jira integration
User prompt: "Write a script that creates a pull request from the current feature branch to main, adds two reviewers, and links it to the Jira ticket ENG-287. Then set up a webhook to notify our Slack channel when PRs are merged."
The agent will:
- Detect the current branch name from git.
- Create a PR via the API with the Jira key ENG-287 in the description for automatic Jira linking, setting
and adding the two reviewer account IDs.close_source_branch: true - Register a webhook listening for
events pointing to the team's webhook endpoint.pullrequest:fulfilled - Provide a webhook handler code snippet that parses the merged PR payload and posts a notification to Slack.
Guidelines
- Use App Passwords for scripts and personal integrations; use OAuth 2.0 for shared applications that act on behalf of multiple users.
- Always set
on pull requests to automatically clean up feature branches after merging.close_source_branch: true - Branch permissions (requiring approvals, blocking direct pushes) require the Bitbucket Premium plan; check your workspace plan before configuring restrictions.
- Use
style tracking with pipeline variables marked--download-archive
for any secrets; secured variables are encrypted and never exposed in build logs.secured: true - Reference Jira issue keys (e.g., ENG-142) in commit messages, branch names, and PR descriptions to get automatic bidirectional linking between Bitbucket and Jira.