Skip to content

feat: add GitHub Runner job template choice - #343

Merged
drappier-charles merged 2 commits into
blaxel-ai:mainfrom
AarjavPatni:apatni/eng-2244-add-job-templates-to-cli-blank-and-github-runner
Aug 6, 2026
Merged

feat: add GitHub Runner job template choice#343
drappier-charles merged 2 commits into
blaxel-ai:mainfrom
AarjavPatni:apatni/eng-2244-add-job-templates-to-cli-blank-and-github-runner

Conversation

@AarjavPatni

@AarjavPatni AarjavPatni commented Jul 10, 2026

Copy link
Copy Markdown
Member

Summary

  • add a job-specific Blank versus GitHub Runner picker backed by the template catalog
  • reuse the existing Python and TypeScript job starters for Blank jobs
  • require explicit templates for non-interactive job creation and provide runner-specific setup guidance
  • validate job template metadata before cloning and preserve [githubRunner] in generated deployment specs

Template and catalog

The official language-neutral template is published at https://github.com/blaxel-templates/template-github-runner. This PR intentionally does not embed its URL or runner assets in toolkit; discovery remains catalog-driven.

The repository contains the complete project at its root:

  • Dockerfile uses a Docker-capable Ubuntu 24.04 GitHub Actions runner image.
  • start.sh starts Docker, configures IPv6/NAT64 egress, downloads execution task data, removes execution credentials from the environment, and starts the runner with its one-use JIT configuration.
  • blaxel.toml declares the job runtime, ephemeral Docker storage, and GitHub repository allow-list.
  • README.md documents deployment, GitHub App installation, runner labels, and settings-only redeployment.
  • examples/workflow.yml provides an inactive workflow users can copy into .github/workflows.

Template discovery and branch selection are separate:

  • The catalog record gives toolkit the canonical name template-github-runner, the official repository URL, and the topics blaxel, job, and github-runner.
  • Toolkit does not use the catalog record's defaultBranch field when cloning. Its existing clone implementation selects main normally and selects develop when BL_ENV is dev or local.
  • The official template repository therefore maintains both branches. They currently point to the same commit and contain identical files.
  • Publishing develop updates the dev catalog record; publishing main updates the production catalog record. This follows the release workflow used by existing blaxel-templates repositories.

At runtime, the Blaxel GitHub integration supplies JIT_CONFIG in execution task data. The template reads that one-use configuration, registers an ephemeral runner, executes one workflow job, and exits.

Verification

  • go test ./...
  • golangci-lint run --new-from-rev=origin/main ./...
  • go build ./...
  • make doc
  • clean review passes covering correctness, security, design, test coverage, and scope
  • dev and production catalog publication workflows succeeded
  • bl new job --list -o json returns template-github-runner from the dev catalog
  • official template deployed successfully as a Blaxel job
  • end-to-end smoke workflow completed successfully on the Blaxel runner: uname -a, docker info, and docker run --rm hello-world

Automatic workflow_job webhook delivery remains dependent on the Blaxel GitHub App's permissions and event subscription; runtime verification used the same one-use JIT task payload directly after the installed App did not deliver that event. This is outside the toolkit change.

Replaces #342 after the source fork was accidentally deleted and recreated.

Linear: ENG-2244


Note

Simplifies the post-scaffolding GitHub Runner setup guidance from 4 steps to 2, removing references to manual blaxel.toml edits and --skip-build deploys. Test assertions updated to match.

Written by Mendral for commit 2ab7645.


Note

Medium Risk
Changes non-interactive job scaffolding semantics (-y without -t now fails) and adds pre-clone validation tied to catalog metadata; scope is CLI UX and deploy spec shaping, not auth or data stores.

Overview
Adds a GitHub Runner path to bl new job, alongside the existing Python/TypeScript blank starters, driven by what appears in the template catalog.

Interactive flow now picks Blank vs GitHub Runner first; runner skips the language picker and blank jobs still use the language/template picker. Non-interactive bl new job -y must pass --template (e.g. github-runner, jobs-py), with validation before clone so runner templates cannot carry a language and blank jobs must match python/typescript metadata.

Job --list output is ordered and sanitized for terminal safety; post-create messaging differs for runner (deploy + console repo setup) vs batch jobs, with generic cd/bl run hints when the directory name is not shell-safe. Docs and examples are updated; deployment generation keeps [githubRunner] in job specs (covered by an integration test).

Reviewed by Cursor Bugbot for commit 2ab7645. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor

cursor Bot commented Jul 10, 2026

Copy link
Copy Markdown

Bugbot is not enabled for this team, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@mendral-app

mendral-app Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

✅ Linked to Linear issue ENG-2244 — status: In Progress

The issue was already in progress and has been linked to this PR.

Note

Posted by Linear Issue Enforcer · Tag @mendral-app with feedback.

mendral-app[bot]

This comment was marked as outdated.

@mendral-app

mendral-app Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

🔀 Interaction Flow Diagram

Here's how the new job template creation flow works based on the changes in this PR:

sequenceDiagram
    participant User
    participant CLI as RunJobCreation
    participant Create as runCreateFlow
    participant JT as job_templates.go
    participant Catalog as RetrieveTemplates
    participant Clone as CloneTemplate

    User->>CLI: bl create-job [dir] [--template] [--yes]
    CLI->>Create: runCreateFlowWithDeps(config)

    alt --yes flag without --template
        Create-->>User: Error: --template required
    end

    Create->>Create: normalizeTemplateNameFlag()
    Create->>Catalog: RetrieveTemplates("job")
    Catalog-->>Create: available templates

    alt No --template flag (interactive)
        Create->>JT: PromptJobTemplateOptions(dir, templates)
        JT->>JT: jobTemplateChoices(templates)

        alt Multiple choices available
            JT->>User: Select job type: Blank / GitHub Runner
            User-->>JT: selection
        end

        alt Blank selected
            JT->>Create: promptTemplateOptions(filtered blank templates)
            Create->>User: Select language: Python / TypeScript
            User-->>Create: language choice
        else GitHub Runner selected
            JT->>JT: CreateDefaultTemplateOptions(dir, runner)
        end

        JT-->>Create: TemplateOptions
    end

    Create->>JT: validateJobTemplateOptions(opts)
    Note over JT: Runner → no language<br/>Blank → must have language

    Create->>Clone: CloneTemplate(opts, templates)
    Clone-->>Create: success

    Create->>JT: printJobCreationSuccess(opts)

    alt Blank job
        JT-->>User: cd dir + sample batch command
    else GitHub Runner
        JT-->>User: Setup instructions (config, deploy, GitHub App)
    end
Loading

Summary of the Flow

This PR introduces a specialized job creation path that branches the user experience based on template type:

Component Role
RunJobCreation (CLI entry) Configures job-specific callbacks and invokes the shared create flow
runCreateFlowWithDeps (create.go) Orchestrates validation → catalog fetch → prompt → clone → success
job_templates.go (NEW) Owns job-specific logic: template discovery, choice routing, validation, and success output
RetrieveTemplates Fetches the template catalog filtered by type
CloneTemplate Performs the actual git clone of the selected template

Key design choices:

  • Early validation — rejects invalid combos (e.g. --yes without --template) before touching the filesystem
  • Smart routing — auto-selects if only one template type is available; shows a picker otherwise
  • Terminal safety — sanitizes template display names against control chars and bidi exploits

Note

Posted by PR Sequence Diagram · Tag @mendral-app with feedback.

@mendral-app

mendral-app Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

🧪 Testing Guide

What this PR addresses

Adds a job-specific template picker to the bl new job CLI command, allowing users to choose between Blank (Python/TypeScript starters) and GitHub Runner job templates. It also enforces --template for non-interactive (--yes) job creation, validates template metadata before cloning, and provides runner-specific setup guidance after scaffolding.

Steps to exercise the new behavior

Interactive flow (requires TTY):

  1. Run bl new job in a terminal
  2. Observe that a "Job type" picker now appears with options: Blank and GitHub Runner (the latter only if template-github-runner is in the catalog)
  3. Select "Blank" → confirm you still get the existing language picker (Python/TypeScript)
  4. Re-run and select "GitHub Runner" → confirm it skips the language picker and scaffolds the runner template directly

Non-interactive flow:
5. Run bl new job my-runner --yes (no --template) → should error with: --template is required when using --yes for job creation
6. Run bl new job my-runner -t github-runner -y → should scaffold successfully and print runner-specific setup instructions (bl deploy, console settings)
7. Run bl new job my-blank -t jobs-py -y → should scaffold the Python blank job and print cd / bl run job instructions

Template listing:
8. Run bl new job --list → confirm it shows jobs-py, jobs-ts, and (if published) github-runner
9. Run bl new job --list -o json → confirm structured output includes the runner template

What to verify (expected behavior)

  • Picker UX: When both Blank and Runner templates are in the catalog, a two-option "Job type" selector appears before any language choice.
  • Single-choice fallback: If only Blank templates exist (runner not published), the picker is skipped and the old language picker shows directly. If only the runner exists, it auto-selects.
  • --yes guard: Non-interactive job creation always requires --template; the error message references bl new job --list.
  • Template validation: Metadata mismatches (e.g., a runner declaring a language, or a blank missing its expected language) produce clear errors before any files are cloned.
  • Success output: Blank jobs print cd + bl run job instructions; GitHub Runner jobs print bl deploy + console guidance. Non-portable directory names get generic phrasing instead of literal shell commands.
  • Structured output: With -o json or -o yaml, non-interactive creation emits machine-readable results (directory, template, language, type) instead of human text.
  • Tests pass: go test ./cli/... should pass, including all new tests in cli/core/create_test.go and cli/core/job_templates_test.go.
  • No regressions: Existing bl new agent / bl new mcp-server flows are unaffected.

Note

Posted by PR Testing Guide · Tag @mendral-app with feedback.

@drappier-charles

Copy link
Copy Markdown
Contributor

You still have this

➜ toolkit git:(apatni/eng-2244-add-job-templates-to-cli-blank-and-github-runner) cd ..
➜ sdk cd ..
➜ Workspace cd demo
➜ demo bl new job gh
✓ Your blaxel job has been created successfully!
Configure your GitHub Runner:
cd gh

  1. Set the allowed owner/repo values in [githubRunner] in blaxel.toml
  2. Run bl deploy
  3. Install the Blaxel GitHub App from the job settings in the Blaxel console
  4. Run bl deploy --skip-build
    ➜ demo cd gh

For me you should simplify by removing the repo/owner from the original path (we can document it in the readme)
But for first XP we could have

1 - bl deploy
2 - Go in UI, and add the repo from UI (we can improve UI if needed)

That's all
Then we can explain in the readme, than for secondary deployment, it's better to add it in toml

@drappier-charles

Copy link
Copy Markdown
Contributor

ALso verify than you are up to date with this repo
https://github.com/blaxel-ai/jobs-image

If you do both of them, just let me know and we merge

@mendral-app mendral-app Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

The incremental change since the last review is a straightforward text simplification with matching test updates. No correctness, security, or logic issues. The strings import removal is correct since strings.Index calls were also removed.

Tag @mendral-app with feedback or questions. View session

@AarjavPatni

Copy link
Copy Markdown
Member Author

@drappier-charles Your comment is implemented.

@drappier-charles
drappier-charles merged commit 05fcae4 into blaxel-ai:main Aug 6, 2026
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants