Files
gh-technicalpickles-pickled…/skills/buildkite-status/references/url-parsing.md
2025-11-30 09:00:26 +08:00

6.8 KiB

Buildkite URL Parsing Reference

This document explains Buildkite URL formats and how to extract information from them.

URL Formats

Buildkite uses several URL patterns for builds and jobs:

Build URL (Most Common)

https://buildkite.com/{org}/{pipeline}/builds/{number}

Example:

https://buildkite.com/gusto/payroll-building-blocks/builds/29627

Extracting:

  • org: "gusto"
  • pipeline: "payroll-building-blocks"
  • number: "29627"

Step/Job URL (From Build Page)

https://buildkite.com/{org}/{pipeline}/builds/{number}/steps/{view}?sid={step-id}

Example:

https://buildkite.com/gusto/payroll-building-blocks/builds/29627/steps/canvas?sid=019a5f23-8109-4656-a033-bd62a82ca239

Extracting:

  • org: "gusto"
  • pipeline: "payroll-building-blocks"
  • number: "29627"
  • view: "canvas" (UI view type)
  • sid: "019a5f23-8109-4656-a033-bd62a82ca239" (step ID)

IMPORTANT: The sid (step ID) is NOT the same as job UUID. See "Step IDs vs Job UUIDs" below.

Job Detail URL

https://buildkite.com/{org}/{pipeline}/builds/{number}/jobs/{job-uuid}

Example:

https://buildkite.com/gusto/payroll-building-blocks/builds/29627/jobs/019a5f20-2d30-4c67-9edd-87fb92e1f487

Extracting:

  • org: "gusto"
  • pipeline: "payroll-building-blocks"
  • number: "29627"
  • job-uuid: "019a5f20-2d30-4c67-9edd-87fb92e1f487"

NOTE: This format contains the actual job UUID needed for log retrieval.

Step IDs vs Job UUIDs

Critical distinction: Buildkite has two types of identifiers that are easily confused.

Step IDs

  • Source: Query parameter sid in step URLs
  • Format: ULID format (e.g., 019a5f23-8109-4656-a033-bd62a82ca239)
  • Purpose: Frontend UI routing
  • Use: Navigating to specific steps in web UI
  • API Usage: NOT accepted by MCP tools

Job UUIDs

  • Source: uuid field in API responses
  • Format: ULID format (e.g., 019a5f20-2d30-4c67-9edd-87fb92e1f487)
  • Purpose: Backend job identification
  • Use: API calls to get logs, job details, etc.
  • API Usage: Required by MCP get_logs tool

Why the Confusion?

Both use ULID format (starts with 019a5f...), but:

  • Step IDs come from URLs → Web UI routing
  • Job UUIDs come from API responses → Backend identification

You cannot use a step ID for log retrieval. Always get job UUID from buildkite:get_build API.

Resolving Step ID to Job UUID

When given a step URL with sid parameter:

Step 1: Extract build identifiers

// From: https://buildkite.com/gusto/payroll-building-blocks/builds/29627/steps/canvas?sid=019a5f23...
const org = 'gusto';
const pipeline = 'payroll-building-blocks';
const build = '29627';
// Ignore the sid parameter

Step 2: Get job details from API

mcp__MCPProxy__call_tool('buildkite:get_build', {
  org_slug: org,
  pipeline_slug: pipeline,
  build_number: build,
  detail_level: 'detailed',
  job_state: 'failed', // If investigating failures
});

Step 3: Match job by properties

The API response includes all jobs. Match by:

  • label field (e.g., "ste rspec", "Rubocop")
  • state field (e.g., "failed")
  • type field (e.g., "script")
  • step_key field if available

Step 4: Extract job UUID

// From API response
const job = response.jobs.find(
  (j) => j.label === 'ste rspec' && j.state === 'failed'
);
const jobUuid = job.uuid; // e.g., "019a5f20-2d30-4c67-9edd-87fb92e1f487"

Step 5: Use job UUID for logs

mcp__MCPProxy__call_tool('buildkite:get_logs', {
  org_slug: org,
  pipeline_slug: pipeline,
  build_number: build,
  job_id: jobUuid, // NOT the step ID from URL
});

Parsing Logic

Simple Regex Approach

function parseBuildkiteUrl(url) {
  // Match build URL pattern
  const buildMatch = url.match(
    /buildkite\.com\/([^/]+)\/([^/]+)\/builds\/(\d+)/
  );

  if (!buildMatch) {
    throw new Error('Invalid Buildkite URL');
  }

  return {
    org: buildMatch[1],
    pipeline: buildMatch[2],
    buildNumber: buildMatch[3],
  };
}

// Usage
const info = parseBuildkiteUrl(
  'https://buildkite.com/gusto/payroll-building-blocks/builds/29627'
);
// => { org: "gusto", pipeline: "payroll-building-blocks", buildNumber: "29627" }

Extracting Step ID (If Needed)

function parseStepUrl(url) {
  const base = parseBuildkiteUrl(url);

  // Extract step ID from query parameter
  const sidMatch = url.match(/[?&]sid=([^&]+)/);

  return {
    ...base,
    stepId: sidMatch ? sidMatch[1] : null,
  };
}

// Usage
const info = parseStepUrl(
  'https://buildkite.com/gusto/payroll-building-blocks/builds/29627/steps/canvas?sid=019a5f23...'
);
// => { org: "gusto", pipeline: "payroll-building-blocks", buildNumber: "29627", stepId: "019a5f23..." }

Remember: The stepId is useful for debugging but cannot be used for API calls. Always fetch job UUID from the API.

Common URL Patterns in Practice

Pattern 1: User Shares Failing Build URL

URL: https://buildkite.com/org/pipeline/builds/123

Workflow:

  1. Extract org/pipeline/build
  2. Call get_build with detail_level: "summary"
  3. Check build state
  4. If failed, call get_build with detail_level: "detailed" and job_state: "failed"
  5. Get logs for each failed job

Pattern 2: User Shares Step URL (Clicked on Specific Job)

URL: https://buildkite.com/org/pipeline/builds/123/steps/canvas?sid=019a5f23...

Workflow:

  1. Extract org/pipeline/build (ignore sid)
  2. Call get_build with detail_level: "detailed"
  3. Find job matching user's intent (often the failed one)
  4. Extract job UUID
  5. Get logs for that job

The sid hints at which job the user was looking at, but you must resolve it via the API.

Pattern 3: User Provides Job UUID Directly

URL: https://buildkite.com/org/pipeline/builds/123/jobs/019a5f20-...

Workflow:

  1. Extract org/pipeline/build/job-uuid
  2. Call get_logs directly with the job UUID
  3. No resolution needed - this is the actual job UUID

This is the ideal format but least common in practice.

Edge Cases

Multiple Jobs with Same Label

Some pipelines parallelize jobs:

  • "rspec (1/10)"
  • "rspec (2/10)"
  • "rspec (3/10)"

When resolving, match the full label string including the partition number.

Dynamic Pipeline Steps

Some pipelines generate steps dynamically. The step structure may not be predictable from the URL alone. Always query the API to see actual job structure.

Retried Jobs

When jobs are retried, multiple job UUIDs exist for the same step. The API returns the most recent attempt. Check retries_count and retry_source fields if investigating retry behavior.

See Also