Skip to main content

Ship code that passes CI on the first try.

Project description

FirstTry

FirstTry makes sure your pull request is green on the first push.
It runs the same checks as your GitHub Actions CI, locally, in seconds — and tells you exactly which step would fail and how to fix it.

Pass CI on the first try.

FirstTry is a pre-commit quality gate that runs the same checks your CI does, locally, before you push. No more "fix lint" commits.

Security Gate: Blocks unsafe shell execution patterns and secret leaks before you ever push to GitHub. This is what your CI wishes it did locally.


FirstTry — Ship Green On The First Try ✅

Quick Start

  • Install: pip install -e . or pip install firsttry
  • Run the pre-commit gate locally: firsttry run --gate pre-commit
  • Install hooks: firsttry install-hooks

Pro vs Free

  • Free: local gating (firsttry gates) that prevents obviously broken commits and surfaces failing steps.
  • Pro: firsttry mirror-ci --run executes your CI steps locally (safe sandbox, denies destructive commands) and requires a license key.

VS Code flow (one-click onboarding)

  • Click the extension Protect this repo action.
  • Extension runs: firsttry init, firsttry install-hooks, firsttry run --gate pre-commit.
  • Extension writes .firsttry.json with install metadata and coverage threshold and surfaces PASS/FAIL inline in the editor.

Quick Start

# Install
pip install firsttry

# Run checks before commit
firsttry run --gate pre-commit

# Install git hooks for automatic checking
firsttry install-hooks

# See what your CI will run
firsttry mirror-ci --root .

Trying FirstTry locally (no install)

You can run FirstTry directly from the repo using Python:

# Check version
python -m firsttry.cli --version

# See if your repo is clean to push (lint, typecheck, etc.)
python -m firsttry.cli gates --json --root .

# Simulate CI locally (requires a license key for --run)
python -m firsttry.cli mirror-ci --root . --run --json --license-key TEST-KEY-OK


python -m firsttry.cli uses the same engine and returns the same JSON you'd get from the packaged firsttry command.

This absolutely matters for onboarding. It means you don’t have to ship wheels or publish to PyPI before giving someone value. You can just DM them the repo and a license key.

And critically: that block makes it crystal clear that `mirror-ci` is gated behind a key. That’s how you start charging.

Fast start — one-command activation

If you want a single command to install hooks, run an initial autofix pass, and finish onboarding, use the activate command we added to the CLI. This is the smoothest way to get FirstTry protecting a repo.

# Install
pip install firsttry

# One-command activation (installs hooks + runs autofix scan)
python -m firsttry.cli activate

What this does:

  • Installs pre-commit and pre-push git hooks for FirstTry.
  • Runs the pre-commit gate once in non-interactive autofix mode (applies safe fixes).
  • Prints onboarding instructions and next steps.

If the initial scan finds issues that require manual attention, activate will still install hooks and print guidance on how to review and finish onboarding.

FirstTry — ship green on the first push

FirstTry runs all your quality gates (lint, typecheck, formatting, etc.) and even simulates your GitHub Actions pipeline locally — safely — so you don't spam PRs with "fix lint lol" commits.

1. Repo Health (Free)

Check if your repo is clean before you push.

firsttry gates --json


or

python -m firsttry.cli gates --json


What this does:

Runs your "pre-commit" / "pre-push" style gates (ruff, mypy, tests, etc.).

Captures returncode, stdout, and stderr from each check.

Never crashes  even if a tool explodes, the result comes back as a structured failure entry.

Returns a single JSON report:

{
  "ok": false,
  "results": [
    {
      "gate": "pre-commit",
      "ok": false,
      > **Public Beta (v0.1.0-beta)**  
      > You can start using FirstTry right now:
      >
      > 1. **CLI setup & workflow**  [GET_STARTED.md](./GET_STARTED.md)  
      > 2. **VS Code extension install**  [INSTALL_VSCODE_EXTENSION.md](./INSTALL_VSCODE_EXTENSION.md)  
      > 3. **Download the extension (.vsix)**  Check the latest Release tagged `v0.1.0-beta`
      >
      > FirstTry = ship code that passes CI on the first try. No more "fix lint lol" commits.

      ````markdown
      # FirstTry

      **FirstTry makes sure your pull request is green on the first push.**  
      It runs the same checks as your GitHub Actions CI, locally, in seconds  and tells you exactly which step would fail and how to fix it.

      **Pass CI on the first try.**

      FirstTry is a pre-commit quality gate that runs the same checks your CI does, locally, before you push. No more "fix lint" commits.

      <!-- ci-trigger: touch to run CI workflows -->

      ## Quick Start

      ```bash
      # Install
      pip install firsttry

      # Run checks before commit
      firsttry run --gate pre-commit

      # Install git hooks for automatic checking
      firsttry install-hooks

      # See what your CI will run
      firsttry mirror-ci --root .
      ```
    "failed_at": {
      "workflow": "ci.yml",
      "job": "build",
      "step": "Run tests",
      "cmd": "pytest -q",
      "stderr": "E    AssertionError: 1 != 0\n",
      "duration_s": 3.24
    }
  }
}

Want early access to Pro? Reach out to our team to request an early access key — we'll enable --run for your account.

Option B: via flag

firsttry mirror-ci --root . --run --json --license-key YOUR-LICENSE-KEY

What this does:

Reads .github/workflows/*.yml

Builds your CI plan (jobs, steps, run commands)

Executes allowed steps locally in order

Blocks obviously dangerous commands with a safety denylist

e.g. rm -rf /, fork bombs, shutdown

Captures stdout / stderr / return codes per step

Returns a structured JSON summary so you know exactly what will fail in PR

If no valid license key is provided:

You still get the dry-run plan (visibility)

But Pro execution (--run) is restricted

This is perfect for:

Senior engineers who are sick of red PRs

Juniors who don't want to look bad on review

Teams that want “CI green on first try”

  1. Safety

We will not run destructive commands. Known-dangerous patterns (like rm -rf /) are denied up front. Blocked steps are reported as:

{ "job": "build", "step": "cleanup", "cmd": "rm -rf /", "status": "blocked", "reason": "blocked_for_safety", "returncode": null, "stdout": "", "stderr": "Command blocked by safety policy" }

So you get transparency without wrecking your machine.

  1. Quality Gates on FirstTry itself

Before we ship anything, we run one command:

AUTOFIX=1 bash local_ci.sh

That enforces:

Ruff + Black formatting

Mypy (0 errors, repo-wide)

Pytest (currently 70+ tests)

Coverage (75%+ across core modules like gates, mirror-ci, licensing, safety)

Node-side checks for supporting extensions / dashboard code

JSON contract tests for both gates and mirror-ci CLI commands

If any of that fails, we don't ship.

This isn’t a toy script. This is production posture.

That block:

  • Teaches what you do in under 2 minutes.
  • Shows off that you're serious (mypy, coverage, safety).
  • Draws a clean pricing line between Free and Pro without using the ugly word "paywall".
  • Gives you screenshots you can post.

Add that to README.md and commit it. That is step one toward onboarding pilot teams.


2. Tiny UX/sales tweaks you should do next

These are easy wins that make demos way more convincing:

(a) Human output mode for firsttry gates

Right now --json prints JSON, which is perfect for your VS Code / Codespaces panel and tests.
For humans (no --json flag), you're already printing a readable summary like:

FirstTry Gates Report
---------------------
[pre-commit] ok=False status=fail returncode=1
[pre-push] ok=True status=pass returncode=0

OVERALL OK: False

Keep that. That’s a screenshot candidate. That goes in README too, as a second example.

(b) Add “Suggested next step”

At the end of that human-readable print in cmd_gates, append something like:

if not all_ok: print("\nTip: Run firsttry gates --json to see exact stdout/stderr for each failed gate.") else: print("\n✓ Repo is clean. You’re safe to push.")

That one line does two things:

It teaches people how to self-diagnose without DMing you.

It markets your JSON format (which is your dashboard API) right inside the CLI.

(c) Screenshot those two commands for marketing:

firsttry gates (failing repo)

firsttry mirror-ci --run --json (with one failing step and one blocked dangerous step)

The second one especially is money because you can say:

“We blocked a destructive command from your CI and still told you what else passed. Your laptop is safe.”

That’s how you close teams.

Roadmap

  • Security baseline noise reducer (group known test/tool files instead of flooding output)

Screenshots / GIFs

Saved example placeholders (replace with real images):

  • docs/screenshots/gates_failure.png — screenshot of firsttry gates with one gate failing
  • docs/screenshots/mirror_ci_failed_at.gif — GIF showing firsttry mirror-ci --run --json highlighting failed_at

Visual demos

We're capturing real CI runs and hook failures and will publish anonymized screenshots and GIFs here after a short private beta. For now, the forensic failed_at JSON block above is the canonical proof of value.

Workflow timing (why devs actually use it)

FirstTry runs in three layers so you don't get slowed down:

  1. pre-commit gate (auto-installed git hook)
  • ~1-3 seconds
  • Lint, imports, basic safety checks
  • Blocks dumb mistakes from even entering your history
  1. pre-push gate
  • ~5-10 seconds (depends on repo)
  • Type-check, smoke tests, DB drift sanity
  • Blocks "oops broke tests" from hitting origin
  1. firsttry mirror-ci --run (Pro)
  • Runs the actual steps from your GitHub Actions locally
  • Stops at the first failing step
  • Gives you a forensic failed_at block with job, step, stderr, and a suggested quick-fix when available
  • Use this before opening a PR so your PR goes green on first try

This three-tier story sells both speed and workflow: quick developer feedback at commit time, broader checks on push, and a full confidence check before your PR.

Local dev requirements

To run pytest -q and to run the Pro CI mirror locally:

  • Python 3.11+
  • pip install -e . from repo root
  • ruff, mypy, pytest installed in your venv (our tests assume they're available)
  • For Pro mode (firsttry mirror-ci --run):
    • set FIRSTTRY_LICENSE_KEY=TEST-KEY-OK for local testing
    • some steps in your GitHub Actions may assume tools you haven't installed locally yet (example: ruff check .). FirstTry will report that failure and stop instantly on that step.

Why this matters: we're honest about local assumptions. If a CI step requires a tool you don't have, FirstTry will tell you quickly so you can install it and re-run.

30-second smoke test

  1. Create and activate a venv and install:
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
  1. Quick health report:
firsttry doctor --json
  1. Preview your CI plan:
firsttry mirror-ci --root .
  1. (Pro preview) simulate running those steps locally:
FIRSTTRY_LICENSE_KEY=TEST-KEY-OK firsttry mirror-ci --root . --run

If step 4 stops with a JSON block that includes "failed_at", that's exactly what would have broken your PR.

Features

🚀 Pre-Commit/Pre-Push Gates

Run quality checks before commits hit CI:

**Output:**

Lint.......... PASS ruff

FirstTry security gate & baseline

FirstTry includes a local CI gate you can run with python -m firsttry.cli run --gate pre-push. It executes linting, type checks, security scans (bandit), and tests with coverage. Findings are grouped into two buckets: (1) unreviewed high-risk security files which will block a push, and (2) baselined files that are known noisy/test/tool paths and are shown for information only. Use python -m firsttry.cli baseline add <glob> to add a path or glob to the baseline and immediately re-run the full gate to see its effect. Format........ PASS black-check Types......... PASS mypy Tests......... PASS pytest Coverage XML.. PASS coverage_xml Coverage Gate. PASS coverage_gate

Verdict: SAFE TO COMMIT ✅

Everything looks good. You'll almost certainly pass CI on the first try.


### 🔍 Mirror CI Locally

See exactly what your GitHub Actions workflows will run:

```bash
firsttry mirror-ci --root .

Example Output:

Workflow: ci.yml
  Job: qa
    Step: Lint
      Run:
        ruff check .
    Step: Test
      Run:
        pytest -q
    Step: Type Check
      Run:
        mypy .

This is your CI plan as a dry-run checklist.

⚙️ Environment Variables

FIRSTTRY_USE_REAL_RUNNERS

Toggle between stub runners (fast, no dependencies) and real analysis tools:

# Use lightweight stubs (default)
firsttry run --gate pre-commit

# Use real ruff, black, mypy, pytest
FIRSTTRY_USE_REAL_RUNNERS=1 firsttry run --gate pre-commit

Why this matters:

  • Stubs: Fast feedback loop during development
  • Real runners: Serious analysis before pushing
  • One env var to flip between "quick sanity" and "CI-grade checks"

Perfect for CI pipelines, pre-push hooks, or when you want confidence.

Installation

pip install firsttry

Or from source:

git clone https://github.com/arnab19111987-ops/Firstry.git
cd Firstry
pip install -e .

Commands

firsttry run

Run a quality gate (pre-commit or pre-push).

firsttry run --gate pre-commit
firsttry run --gate pre-push
firsttry run --gate pre-commit --require-license

When something fails, FirstTry explains exactly what broke and how to fix it.

Example:

--- Format (black) FAILED ---
Fix:
  Run: black .

--- Lint (ruff) FAILED ---
Fix:
  Run: ruff --fix .

Options:

  • --gate: Which gate to run (pre-commit | pre-push)
  • --require-license: Fail if license check fails

firsttry install-hooks

Install git hooks that automatically run FirstTry before commits/pushes.

firsttry install-hooks

Creates:

  • .git/hooks/pre-commit - Runs pre-commit gate
  • .git/hooks/pre-push - Runs pre-push gate

firsttry mirror-ci

Show what CI workflows will run, locally.

firsttry mirror-ci --root .

Options:

  • --root: Project root containing .github/workflows (default: .)

Runners API (Semi-Stable)

FirstTry's runner interface is semi-stable. You can build alternate runner packs by implementing:

from types import SimpleNamespace

def run_ruff(args) -> SimpleNamespace:
    """Run ruff linter."""
    return SimpleNamespace(
        ok=True,           # bool: did the check pass?
        name="ruff",       # str: runner name
        duration_s=0.5,    # float: how long it took
        stdout="",         # str: command stdout
        stderr="",         # str: command stderr
        cmd=("ruff", ...") # tuple: command that ran
    )

def run_black_check(args) -> SimpleNamespace:
    """Run black formatter check."""
    # Same signature as above

def run_mypy(args) -> SimpleNamespace:
    """Run mypy type checker."""
    # Same signature as above

Why you'd want this:

  • Ship alternate tool sets (ruff → pylint, black → yapf)
  • Add company-specific checks
  • Integrate proprietary analysis tools

Place your runners in tools/firsttry/firsttry/runners.py and set FIRSTTRY_USE_REAL_RUNNERS=1.

Development

# Run tests
pytest -q

# Run with real runners
FIRSTTRY_USE_REAL_RUNNERS=1 pytest -q

# Install in editable mode
pip install -e .

License

MIT

Tags & Branches

  • firsttry-core-v0.1: First stable release, 42/42 tests passing, hardened runner loader
  • feat/firsttry-stable-core: Development branch for stable core features

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

firsttry_run-0.1.7.tar.gz (120.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

firsttry_run-0.1.7-py3-none-any.whl (110.4 kB view details)

Uploaded Python 3

File details

Details for the file firsttry_run-0.1.7.tar.gz.

File metadata

  • Download URL: firsttry_run-0.1.7.tar.gz
  • Upload date:
  • Size: 120.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.1

File hashes

Hashes for firsttry_run-0.1.7.tar.gz
Algorithm Hash digest
SHA256 b06e08358e3b3b429b9ecc6ded42205b0ce380d4d5839cdcd7406d19164db75b
MD5 c7cdda6c4e02a14f19c3816ebf5964a3
BLAKE2b-256 44f9a0c4994a7adf4b7f52da807b3a4dd0f83518f904f3e527f10f5b1e0b3119

See more details on using hashes here.

File details

Details for the file firsttry_run-0.1.7-py3-none-any.whl.

File metadata

  • Download URL: firsttry_run-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 110.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.1

File hashes

Hashes for firsttry_run-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 f360e05e9ec0b4a3a2b305f901ad74d532e62e03573a553d428a751523f104be
MD5 383bc4ef560637657e3910e7873be419
BLAKE2b-256 db162788cd76984230ebbd52b29b736ed6e834536eb5c2290c16c8154ec90456

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page