mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-08-28 05:27:41 +00:00
Refactor: Collapse pull_request fields on RunConfig into Option<PullRequestConfig> (#21)
This refactoring collapses four flat `pull_request_*` fields on
`RunConfig` (`pull_request_enabled`, `pull_request_draft`,
`pull_request_auto_merge`, `pull_request_merge_strategy`) into a single
`pull_request: Option<PullRequestConfig>` field. This better represents
the natural tree structure of the configuration: `None` means PR
creation is disabled, while `Some(config)` carries all PR settings
directly.
The PR creation logic in `run.rs` is restructured to use `if let
Some(ref pr_cfg) = config.pull_request` instead of checking a boolean
flag, and construction is simplified to filter out disabled configs at
build time via `.filter(|p| p.enabled).cloned()`. All test constructors
across `engine.rs`, `integration.rs`, `daytona_integration.rs`,
`server.rs`, and `manager_loop.rs` are updated from two lines
(`pull_request_enabled: false, pull_request_draft: false/true`) to a
single `pull_request: None`.
### Fabro Details
<details>
<summary>Ran 10 stages in 20m 32s for $6.62</summary>
| Stage | Duration | Cost | Retries |
|---|---|---|---|
| start | 0s | – | 0 |
| toolchain | 0s | – | 0 |
| preflight_compile | 0s | – | 0 |
| preflight_lint | 0s | – | 0 |
| implement | 0s | $1.71 | 0 |
| simplify_opus | 0s | $1.63 | 0 |
| simplify_gemini | 0s | $1.74 | 0 |
| simplify_gpt | 0s | $1.55 | 0 |
| verify | 0s | – | 0 |
| fmt | 0s | – | 0 |
| **Total** | **20m 32s** | **$6.62** | **0** |
</details>
<details>
<summary>Ran <code>ImplementAndSimplify.fabro</code> (13 nodes and 16
edges)</summary>
```dot
digraph ImplementAndSimplify {
graph [
goal="Implement and simplify",
model_stylesheet="
* { backend: api; model: claude-opus-4-6;}
"
]
rankdir=LR
start [shape=Mdiamond, label="Start"]
exit [shape=Msquare, label="Exit"]
toolchain [label="Toolchain", shape=parallelogram, script="command -v cargo >/dev/null || { curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && sudo ln -sf $HOME/.cargo/bin/* /usr/local/bin/; }; cargo --version 2>&1", max_retries=0]
preflight_compile [label="Preflight Compile", shape=parallelogram, script="cargo check -q --workspace 2>&1", max_retries=0]
preflight_lint [label="Preflight Lint", shape=parallelogram, script="cargo clippy -q --workspace -- -D warnings 2>&1", max_retries=0]
fix_lints [label="Fix Lints", prompt="The preflight lint step failed. Read the build output from context and fix all clippy lint warnings.", max_visits=3]
implement [label="Implement", prompt="Read the plan file referenced in the goal and implement every step. Make all the code changes described in the plan. Use red/green TDD."]
simplify_opus [label="Simplify (Opus)", prompt="@prompts/simplify.md"]
simplify_gemini [label="Simplify (Gemini)", prompt="@prompts/simplify.md", model="gemini-3.1-pro-preview-customtools"]
simplify_gpt [label="Simplify (GPT-54)", prompt="@prompts/simplify.md", model="gpt-54"]
verify [label="Verify", shape=parallelogram, script="cargo clippy -q --workspace -- -D warnings 2>&1 && cargo nextest run --cargo-quiet --workspace --status-level fail 2>&1", goal_gate=true, retry_target="fixup"]
fixup [label="Fixup", prompt="The verify step failed. Read the build output from context and fix all clippy lint warnings and test failures.", max_visits=3]
fmt [label="Format", shape=parallelogram, script="cargo fmt --all 2>&1", goal_gate=true, max_retries=0]
start -> toolchain
toolchain -> preflight_compile [condition="outcome=success"]
toolchain -> exit
preflight_compile -> preflight_lint [condition="outcome=success"]
preflight_compile -> exit
preflight_lint -> implement [condition="outcome=success"]
preflight_lint -> fix_lints
fix_lints -> preflight_lint
implement -> simplify_opus -> simplify_gemini -> simplify_gpt -> verify
verify -> fmt [condition="outcome=success"]
verify -> fixup
fixup -> verify
fmt -> exit
}
```
</details>
⚒️ Generated with [Fabro](https://fabro.sh)
---------
Co-authored-by: Fabro <noreply@fabro.sh>
Co-authored-by: Bryan Helmkamp <bryan@brynary.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
469b5d4670
commit
74dae0a342
7 changed files with 925 additions and 753 deletions
673
apps/marketing/font-comparison.html
Normal file
673
apps/marketing/font-comparison.html
Normal file
|
|
@ -0,0 +1,673 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Fabro — Font Treatment Comparison</title>
|
||||
|
||||
<!-- Current fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,600;9..40,700&family=JetBrains+Mono:wght@400;500&family=Outfit:wght@400;500;600;700&family=Lexend:wght@400;500;600;700&family=Fira+Code:wght@400;500&family=Instrument+Serif:ital@0;1&family=Instrument+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400&family=IBM+Plex+Mono:wght@400;500&family=Syne:wght@400;500;600;700;800&family=Manrope:wght@400;500;600;700&family=Source+Code+Pro:wght@400;500&display=swap" rel="stylesheet" />
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--navy-950: #0F1729;
|
||||
--navy-900: #141C2F;
|
||||
--navy-800: #252C3D;
|
||||
--navy-600: #4B5768;
|
||||
--teal-300: #B5DDEF;
|
||||
--teal-500: #67B2D7;
|
||||
--teal-700: #357F9E;
|
||||
--ice-50: #F7F9FB;
|
||||
--ice-100: #E8EDF3;
|
||||
--ice-300: #A8B5C5;
|
||||
--mint: #5AC8A8;
|
||||
--amber: #F0A45B;
|
||||
--coral: #E86B6B;
|
||||
}
|
||||
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
background: var(--navy-950);
|
||||
color: var(--ice-50);
|
||||
min-height: 100vh;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
/* ── Page header ── */
|
||||
.page-header {
|
||||
text-align: center;
|
||||
padding: 48px 24px 24px;
|
||||
border-bottom: 1px solid var(--navy-800);
|
||||
}
|
||||
.page-header h1 {
|
||||
font-family: 'Space Grotesk', sans-serif;
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
color: var(--ice-50);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.page-header p {
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
font-size: 15px;
|
||||
color: var(--ice-300);
|
||||
}
|
||||
|
||||
/* ── Selector bar ── */
|
||||
.selector-bar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 50;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
padding: 16px 24px;
|
||||
background: var(--navy-950);
|
||||
border-bottom: 1px solid var(--navy-800);
|
||||
backdrop-filter: blur(16px);
|
||||
}
|
||||
.selector-btn {
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
padding: 8px 20px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--navy-600);
|
||||
background: transparent;
|
||||
color: var(--ice-300);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.selector-btn:hover {
|
||||
border-color: var(--teal-500);
|
||||
color: var(--ice-50);
|
||||
}
|
||||
.selector-btn.active {
|
||||
background: var(--teal-700);
|
||||
border-color: var(--teal-700);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* ── Layout ── */
|
||||
.treatments {
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.treatment {
|
||||
display: none;
|
||||
padding: 48px 24px 80px;
|
||||
}
|
||||
.treatment.visible { display: block; }
|
||||
|
||||
.treatment-label {
|
||||
text-align: center;
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
.treatment-label .tag {
|
||||
display: inline-block;
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: var(--teal-300);
|
||||
background: rgba(53, 127, 158, 0.15);
|
||||
border: 1px solid rgba(53, 127, 158, 0.3);
|
||||
padding: 4px 14px;
|
||||
border-radius: 100px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.treatment-label h2 {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: var(--ice-50);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.treatment-label .fonts-list {
|
||||
font-size: 13px;
|
||||
color: var(--ice-300);
|
||||
}
|
||||
.treatment-label .fonts-list span {
|
||||
color: var(--teal-300);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* ── Sample sections ── */
|
||||
.samples {
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 56px;
|
||||
}
|
||||
|
||||
/* Nav sample */
|
||||
.sample-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px 24px;
|
||||
border: 1px solid var(--navy-800);
|
||||
border-radius: 12px;
|
||||
background: var(--navy-900);
|
||||
}
|
||||
.sample-nav .logo { font-weight: 700; font-size: 22px; }
|
||||
.sample-nav .links {
|
||||
display: flex;
|
||||
gap: 28px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--ice-100);
|
||||
}
|
||||
.sample-nav .cta-btn {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
padding: 8px 18px;
|
||||
border-radius: 8px;
|
||||
background: var(--teal-700);
|
||||
color: white;
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Hero sample */
|
||||
.sample-hero {
|
||||
text-align: center;
|
||||
}
|
||||
.sample-hero .badge {
|
||||
display: inline-block;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: var(--teal-300);
|
||||
border: 1px solid rgba(53, 127, 158, 0.35);
|
||||
background: rgba(53, 127, 158, 0.08);
|
||||
padding: 6px 16px;
|
||||
border-radius: 100px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.sample-hero h3 {
|
||||
font-size: 52px;
|
||||
font-weight: 700;
|
||||
line-height: 1.08;
|
||||
letter-spacing: -0.025em;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.sample-hero h3 .gradient {
|
||||
background: linear-gradient(135deg, var(--teal-300), var(--mint), var(--teal-500));
|
||||
background-size: 200% 200%;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
.sample-hero .subtitle {
|
||||
font-size: 18px;
|
||||
line-height: 1.65;
|
||||
color: var(--ice-300);
|
||||
max-width: 580px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Feature cards */
|
||||
.sample-features {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
.feature-card {
|
||||
padding: 28px 24px;
|
||||
border: 1px solid var(--navy-800);
|
||||
border-radius: 12px;
|
||||
background: linear-gradient(to bottom, var(--navy-900), var(--navy-950));
|
||||
transition: border-color 0.3s, box-shadow 0.3s, transform 0.3s;
|
||||
}
|
||||
.feature-card:hover {
|
||||
border-color: rgba(103, 178, 215, 0.25);
|
||||
box-shadow: 0 0 40px -8px rgba(103, 178, 215, 0.12);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.feature-card .icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 8px;
|
||||
background: rgba(53, 127, 158, 0.12);
|
||||
border: 1px solid rgba(53, 127, 158, 0.2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 16px;
|
||||
color: var(--teal-300);
|
||||
font-size: 16px;
|
||||
}
|
||||
.feature-card h4 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
color: var(--ice-50);
|
||||
}
|
||||
.feature-card p {
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
color: var(--ice-300);
|
||||
}
|
||||
|
||||
/* Code sample */
|
||||
.sample-code {
|
||||
border: 1px solid var(--navy-800);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
background: var(--navy-900);
|
||||
}
|
||||
.sample-code .code-header {
|
||||
padding: 12px 20px;
|
||||
border-bottom: 1px solid var(--navy-800);
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: var(--ice-300);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.sample-code .code-header .dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: var(--mint);
|
||||
opacity: 0.6;
|
||||
}
|
||||
.sample-code pre {
|
||||
padding: 24px;
|
||||
font-size: 13.5px;
|
||||
line-height: 1.7;
|
||||
overflow-x: auto;
|
||||
color: var(--ice-300);
|
||||
}
|
||||
.sample-code .kw { color: var(--teal-300); }
|
||||
.sample-code .fn { color: var(--ice-50); }
|
||||
.sample-code .prop { color: var(--teal-500); }
|
||||
.sample-code .str { color: var(--ice-300); }
|
||||
.sample-code .cm { color: var(--navy-600); }
|
||||
|
||||
/* Body text sample */
|
||||
.sample-prose {
|
||||
max-width: 640px;
|
||||
}
|
||||
.sample-prose h4 {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 16px;
|
||||
color: var(--ice-50);
|
||||
}
|
||||
.sample-prose p {
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
color: var(--ice-300);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.sample-prose a {
|
||||
color: var(--teal-300);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
}
|
||||
.sample-prose code {
|
||||
font-size: 0.875em;
|
||||
background: var(--navy-800);
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
color: var(--teal-300);
|
||||
}
|
||||
|
||||
/* ── Side by side mode ── */
|
||||
.grid-view {
|
||||
display: none;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0;
|
||||
}
|
||||
.grid-view.visible { display: grid; }
|
||||
.grid-view .treatment {
|
||||
display: block;
|
||||
padding: 40px 20px 60px;
|
||||
border-right: 1px solid var(--navy-800);
|
||||
}
|
||||
.grid-view .treatment:last-child { border-right: none; }
|
||||
.grid-view .samples { gap: 40px; }
|
||||
.grid-view .sample-hero h3 { font-size: 32px; }
|
||||
.grid-view .sample-hero .subtitle { font-size: 15px; }
|
||||
.grid-view .sample-features { grid-template-columns: 1fr; }
|
||||
.grid-view .sample-nav { padding: 12px 16px; }
|
||||
.grid-view .sample-nav .links { display: none; }
|
||||
.grid-view .sample-prose h4 { font-size: 20px; }
|
||||
.grid-view .sample-prose p { font-size: 14px; }
|
||||
.grid-view .sample-code pre { font-size: 12px; }
|
||||
|
||||
/* ── Font family assignments ── */
|
||||
|
||||
/* Current: Space Grotesk / DM Sans / JetBrains Mono */
|
||||
.t-current .display { font-family: 'Space Grotesk', sans-serif; }
|
||||
.t-current .body { font-family: 'DM Sans', sans-serif; }
|
||||
.t-current .mono { font-family: 'JetBrains Mono', monospace; }
|
||||
|
||||
/* A: Outfit / Lexend / Fira Code */
|
||||
.t-a .display { font-family: 'Outfit', sans-serif; }
|
||||
.t-a .body { font-family: 'Lexend', sans-serif; }
|
||||
.t-a .mono { font-family: 'Fira Code', monospace; }
|
||||
|
||||
/* B: Instrument Serif / Instrument Sans / IBM Plex Mono */
|
||||
.t-b .display { font-family: 'Instrument Serif', serif; }
|
||||
.t-b .body { font-family: 'Instrument Sans', sans-serif; }
|
||||
.t-b .mono { font-family: 'IBM Plex Mono', monospace; }
|
||||
|
||||
/* C: Syne / Manrope / Source Code Pro */
|
||||
.t-c .display { font-family: 'Syne', sans-serif; }
|
||||
.t-c .body { font-family: 'Manrope', sans-serif; }
|
||||
.t-c .mono { font-family: 'Source Code Pro', monospace; }
|
||||
|
||||
/* view toggle */
|
||||
.view-toggle {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
margin-left: auto;
|
||||
}
|
||||
.view-btn {
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
padding: 6px 12px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--navy-800);
|
||||
background: transparent;
|
||||
color: var(--ice-300);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.view-btn.active {
|
||||
background: var(--navy-800);
|
||||
color: var(--ice-50);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.sample-features { grid-template-columns: 1fr; }
|
||||
.sample-hero h3 { font-size: 36px; }
|
||||
.grid-view { grid-template-columns: 1fr; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Font Treatment Comparison</h1>
|
||||
<p>Comparing the current Fabro marketing site fonts against 3 alternatives</p>
|
||||
</div>
|
||||
|
||||
<div class="selector-bar">
|
||||
<button class="selector-btn active" data-target="current" onclick="show('current')">Current</button>
|
||||
<button class="selector-btn" data-target="a" onclick="show('a')">A: Razor Geometric</button>
|
||||
<button class="selector-btn" data-target="b" onclick="show('b')">B: Editorial Contrast</button>
|
||||
<button class="selector-btn" data-target="c" onclick="show('c')">C: Bold Industrial</button>
|
||||
<div class="view-toggle">
|
||||
<button class="view-btn active" onclick="setView('single')">Single</button>
|
||||
<button class="view-btn" onclick="setView('grid')">2-up</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════════════════════════════ SINGLE VIEW ═══════════════════════════════════════ -->
|
||||
<div class="treatments single-view" id="single-view">
|
||||
|
||||
<!-- CURRENT -->
|
||||
<div class="treatment t-current visible" data-id="current">
|
||||
<div class="treatment-label">
|
||||
<div class="tag">Current</div>
|
||||
<h2 class="display">Space Grotesk + DM Sans + JetBrains Mono</h2>
|
||||
<p class="fonts-list body">Display: <span>Space Grotesk</span> · Body: <span>DM Sans</span> · Mono: <span>JetBrains Mono</span></p>
|
||||
</div>
|
||||
<div class="samples">
|
||||
<div class="sample-nav">
|
||||
<div class="logo display">fabro</div>
|
||||
<div class="links body"><span>Docs</span><span>Blog</span><span>Showcase</span><span>Roadmap</span></div>
|
||||
<button class="cta-btn body">Get started</button>
|
||||
</div>
|
||||
<div class="sample-hero">
|
||||
<div class="badge body">Open source workflow engine</div>
|
||||
<h3 class="display">The dark software factory<br/>for <span class="gradient">expert engineers</span></h3>
|
||||
<p class="subtitle body">Stop babysitting agents. Define your process as a workflow graph, let AI agents execute it, and intervene only where it matters.</p>
|
||||
</div>
|
||||
<div class="sample-features">
|
||||
<div class="feature-card"><div class="icon">◉</div><h4 class="display">Workflow graphs</h4><p class="body">Define multi-step processes as Graphviz directed graphs. Each node is a stage with its own prompt, model, and tools.</p></div>
|
||||
<div class="feature-card"><div class="icon">⬡</div><h4 class="display">Human-in-the-loop</h4><p class="body">Hexagonal approval gates let humans review, revise, or override at any point in the workflow.</p></div>
|
||||
<div class="feature-card"><div class="icon">⦾</div><h4 class="display">Multi-model routing</h4><p class="body">Assign models per-stage with CSS-like selectors. Use Haiku for triage, Sonnet for code, Gemini for review.</p></div>
|
||||
</div>
|
||||
<div class="sample-code">
|
||||
<div class="code-header mono"><div class="dot"></div>workflow.dot</div>
|
||||
<pre class="mono"><span class="kw">digraph</span> <span class="fn">PlanImplement</span> {
|
||||
<span class="kw">graph</span> [
|
||||
<span class="prop">goal</span>=<span class="str">"Plan, approve, implement, and simplify"</span>
|
||||
]
|
||||
|
||||
<span class="prop">plan</span> [label=<span class="str">"Plan"</span>]
|
||||
<span class="prop">approve</span> [shape=hexagon, label=<span class="str">"Approve Plan"</span>]
|
||||
<span class="prop">implement</span> [label=<span class="str">"Implement"</span>, class=<span class="str">"coding"</span>]
|
||||
|
||||
<span class="str">start -> plan -> approve -> implement -> exit</span>
|
||||
}</pre>
|
||||
</div>
|
||||
<div class="sample-prose">
|
||||
<h4 class="display">Verification is a first-class concept</h4>
|
||||
<p class="body">Every workflow can include build gates, test assertions, and human approval stages. When a stage fails, Fabro routes back to the appropriate fix loop — no manual re-runs, no <code class="mono">git stash</code> gymnastics.</p>
|
||||
<p class="body">The <a href="#">retrospective engine</a> runs after every workflow, surfacing what went wrong and why. Over time, your workflows get smarter.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- OPTION A: Razor Geometric -->
|
||||
<div class="treatment t-a" data-id="a">
|
||||
<div class="treatment-label">
|
||||
<div class="tag">Option A</div>
|
||||
<h2 class="display">Outfit + Lexend + Fira Code</h2>
|
||||
<p class="fonts-list body">Display: <span>Outfit</span> · Body: <span>Lexend</span> · Mono: <span>Fira Code</span></p>
|
||||
</div>
|
||||
<div class="samples">
|
||||
<div class="sample-nav">
|
||||
<div class="logo display">fabro</div>
|
||||
<div class="links body"><span>Docs</span><span>Blog</span><span>Showcase</span><span>Roadmap</span></div>
|
||||
<button class="cta-btn body">Get started</button>
|
||||
</div>
|
||||
<div class="sample-hero">
|
||||
<div class="badge body">Open source workflow engine</div>
|
||||
<h3 class="display">The dark software factory<br/>for <span class="gradient">expert engineers</span></h3>
|
||||
<p class="subtitle body">Stop babysitting agents. Define your process as a workflow graph, let AI agents execute it, and intervene only where it matters.</p>
|
||||
</div>
|
||||
<div class="sample-features">
|
||||
<div class="feature-card"><div class="icon">◉</div><h4 class="display">Workflow graphs</h4><p class="body">Define multi-step processes as Graphviz directed graphs. Each node is a stage with its own prompt, model, and tools.</p></div>
|
||||
<div class="feature-card"><div class="icon">⬡</div><h4 class="display">Human-in-the-loop</h4><p class="body">Hexagonal approval gates let humans review, revise, or override at any point in the workflow.</p></div>
|
||||
<div class="feature-card"><div class="icon">⦾</div><h4 class="display">Multi-model routing</h4><p class="body">Assign models per-stage with CSS-like selectors. Use Haiku for triage, Sonnet for code, Gemini for review.</p></div>
|
||||
</div>
|
||||
<div class="sample-code">
|
||||
<div class="code-header mono"><div class="dot"></div>workflow.dot</div>
|
||||
<pre class="mono"><span class="kw">digraph</span> <span class="fn">PlanImplement</span> {
|
||||
<span class="kw">graph</span> [
|
||||
<span class="prop">goal</span>=<span class="str">"Plan, approve, implement, and simplify"</span>
|
||||
]
|
||||
|
||||
<span class="prop">plan</span> [label=<span class="str">"Plan"</span>]
|
||||
<span class="prop">approve</span> [shape=hexagon, label=<span class="str">"Approve Plan"</span>]
|
||||
<span class="prop">implement</span> [label=<span class="str">"Implement"</span>, class=<span class="str">"coding"</span>]
|
||||
|
||||
<span class="str">start -> plan -> approve -> implement -> exit</span>
|
||||
}</pre>
|
||||
</div>
|
||||
<div class="sample-prose">
|
||||
<h4 class="display">Verification is a first-class concept</h4>
|
||||
<p class="body">Every workflow can include build gates, test assertions, and human approval stages. When a stage fails, Fabro routes back to the appropriate fix loop — no manual re-runs, no <code class="mono">git stash</code> gymnastics.</p>
|
||||
<p class="body">The <a href="#">retrospective engine</a> runs after every workflow, surfacing what went wrong and why. Over time, your workflows get smarter.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- OPTION B: Editorial Contrast -->
|
||||
<div class="treatment t-b" data-id="b">
|
||||
<div class="treatment-label">
|
||||
<div class="tag">Option B</div>
|
||||
<h2 class="display">Instrument Serif + Instrument Sans + IBM Plex Mono</h2>
|
||||
<p class="fonts-list body">Display: <span>Instrument Serif</span> · Body: <span>Instrument Sans</span> · Mono: <span>IBM Plex Mono</span></p>
|
||||
</div>
|
||||
<div class="samples">
|
||||
<div class="sample-nav">
|
||||
<div class="logo display">fabro</div>
|
||||
<div class="links body"><span>Docs</span><span>Blog</span><span>Showcase</span><span>Roadmap</span></div>
|
||||
<button class="cta-btn body">Get started</button>
|
||||
</div>
|
||||
<div class="sample-hero">
|
||||
<div class="badge body">Open source workflow engine</div>
|
||||
<h3 class="display">The dark software factory<br/>for <span class="gradient">expert engineers</span></h3>
|
||||
<p class="subtitle body">Stop babysitting agents. Define your process as a workflow graph, let AI agents execute it, and intervene only where it matters.</p>
|
||||
</div>
|
||||
<div class="sample-features">
|
||||
<div class="feature-card"><div class="icon">◉</div><h4 class="display">Workflow graphs</h4><p class="body">Define multi-step processes as Graphviz directed graphs. Each node is a stage with its own prompt, model, and tools.</p></div>
|
||||
<div class="feature-card"><div class="icon">⬡</div><h4 class="display">Human-in-the-loop</h4><p class="body">Hexagonal approval gates let humans review, revise, or override at any point in the workflow.</p></div>
|
||||
<div class="feature-card"><div class="icon">⦾</div><h4 class="display">Multi-model routing</h4><p class="body">Assign models per-stage with CSS-like selectors. Use Haiku for triage, Sonnet for code, Gemini for review.</p></div>
|
||||
</div>
|
||||
<div class="sample-code">
|
||||
<div class="code-header mono"><div class="dot"></div>workflow.dot</div>
|
||||
<pre class="mono"><span class="kw">digraph</span> <span class="fn">PlanImplement</span> {
|
||||
<span class="kw">graph</span> [
|
||||
<span class="prop">goal</span>=<span class="str">"Plan, approve, implement, and simplify"</span>
|
||||
]
|
||||
|
||||
<span class="prop">plan</span> [label=<span class="str">"Plan"</span>]
|
||||
<span class="prop">approve</span> [shape=hexagon, label=<span class="str">"Approve Plan"</span>]
|
||||
<span class="prop">implement</span> [label=<span class="str">"Implement"</span>, class=<span class="str">"coding"</span>]
|
||||
|
||||
<span class="str">start -> plan -> approve -> implement -> exit</span>
|
||||
}</pre>
|
||||
</div>
|
||||
<div class="sample-prose">
|
||||
<h4 class="display">Verification is a first-class concept</h4>
|
||||
<p class="body">Every workflow can include build gates, test assertions, and human approval stages. When a stage fails, Fabro routes back to the appropriate fix loop — no manual re-runs, no <code class="mono">git stash</code> gymnastics.</p>
|
||||
<p class="body">The <a href="#">retrospective engine</a> runs after every workflow, surfacing what went wrong and why. Over time, your workflows get smarter.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- OPTION C: Bold Industrial -->
|
||||
<div class="treatment t-c" data-id="c">
|
||||
<div class="treatment-label">
|
||||
<div class="tag">Option C</div>
|
||||
<h2 class="display">Syne + Manrope + Source Code Pro</h2>
|
||||
<p class="fonts-list body">Display: <span>Syne</span> · Body: <span>Manrope</span> · Mono: <span>Source Code Pro</span></p>
|
||||
</div>
|
||||
<div class="samples">
|
||||
<div class="sample-nav">
|
||||
<div class="logo display">fabro</div>
|
||||
<div class="links body"><span>Docs</span><span>Blog</span><span>Showcase</span><span>Roadmap</span></div>
|
||||
<button class="cta-btn body">Get started</button>
|
||||
</div>
|
||||
<div class="sample-hero">
|
||||
<div class="badge body">Open source workflow engine</div>
|
||||
<h3 class="display">The dark software factory<br/>for <span class="gradient">expert engineers</span></h3>
|
||||
<p class="subtitle body">Stop babysitting agents. Define your process as a workflow graph, let AI agents execute it, and intervene only where it matters.</p>
|
||||
</div>
|
||||
<div class="sample-features">
|
||||
<div class="feature-card"><div class="icon">◉</div><h4 class="display">Workflow graphs</h4><p class="body">Define multi-step processes as Graphviz directed graphs. Each node is a stage with its own prompt, model, and tools.</p></div>
|
||||
<div class="feature-card"><div class="icon">⬡</div><h4 class="display">Human-in-the-loop</h4><p class="body">Hexagonal approval gates let humans review, revise, or override at any point in the workflow.</p></div>
|
||||
<div class="feature-card"><div class="icon">⦾</div><h4 class="display">Multi-model routing</h4><p class="body">Assign models per-stage with CSS-like selectors. Use Haiku for triage, Sonnet for code, Gemini for review.</p></div>
|
||||
</div>
|
||||
<div class="sample-code">
|
||||
<div class="code-header mono"><div class="dot"></div>workflow.dot</div>
|
||||
<pre class="mono"><span class="kw">digraph</span> <span class="fn">PlanImplement</span> {
|
||||
<span class="kw">graph</span> [
|
||||
<span class="prop">goal</span>=<span class="str">"Plan, approve, implement, and simplify"</span>
|
||||
]
|
||||
|
||||
<span class="prop">plan</span> [label=<span class="str">"Plan"</span>]
|
||||
<span class="prop">approve</span> [shape=hexagon, label=<span class="str">"Approve Plan"</span>]
|
||||
<span class="prop">implement</span> [label=<span class="str">"Implement"</span>, class=<span class="str">"coding"</span>]
|
||||
|
||||
<span class="str">start -> plan -> approve -> implement -> exit</span>
|
||||
}</pre>
|
||||
</div>
|
||||
<div class="sample-prose">
|
||||
<h4 class="display">Verification is a first-class concept</h4>
|
||||
<p class="body">Every workflow can include build gates, test assertions, and human approval stages. When a stage fails, Fabro routes back to the appropriate fix loop — no manual re-runs, no <code class="mono">git stash</code> gymnastics.</p>
|
||||
<p class="body">The <a href="#">retrospective engine</a> runs after every workflow, surfacing what went wrong and why. Over time, your workflows get smarter.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ═══════════════════════════════════════ GRID VIEW ═══════════════════════════════════════ -->
|
||||
<div class="grid-view" id="grid-view">
|
||||
<!-- filled dynamically -->
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let currentView = 'single';
|
||||
let activeIds = ['current'];
|
||||
|
||||
function show(id) {
|
||||
if (currentView === 'single') {
|
||||
activeIds = [id];
|
||||
document.querySelectorAll('#single-view .treatment').forEach(el => {
|
||||
el.classList.toggle('visible', el.dataset.id === id);
|
||||
});
|
||||
} else {
|
||||
// grid: toggle
|
||||
const idx = activeIds.indexOf(id);
|
||||
if (idx > -1) {
|
||||
if (activeIds.length > 1) activeIds.splice(idx, 1);
|
||||
} else {
|
||||
if (activeIds.length >= 2) activeIds.shift();
|
||||
activeIds.push(id);
|
||||
}
|
||||
renderGrid();
|
||||
}
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
function updateButtons() {
|
||||
document.querySelectorAll('.selector-btn').forEach(btn => {
|
||||
btn.classList.toggle('active', activeIds.includes(btn.dataset.target));
|
||||
});
|
||||
}
|
||||
|
||||
function setView(v) {
|
||||
currentView = v;
|
||||
document.querySelectorAll('.view-btn').forEach(b => b.classList.remove('active'));
|
||||
document.querySelector(`.view-btn[onclick="setView('${v}')"]`).classList.add('active');
|
||||
|
||||
if (v === 'single') {
|
||||
document.getElementById('single-view').style.display = 'block';
|
||||
document.getElementById('grid-view').classList.remove('visible');
|
||||
if (activeIds.length > 1) activeIds = [activeIds[0]];
|
||||
document.querySelectorAll('#single-view .treatment').forEach(el => {
|
||||
el.classList.toggle('visible', el.dataset.id === activeIds[0]);
|
||||
});
|
||||
} else {
|
||||
document.getElementById('single-view').style.display = 'none';
|
||||
if (activeIds.length < 2) {
|
||||
const all = ['current', 'a', 'b', 'c'];
|
||||
const next = all.find(x => !activeIds.includes(x));
|
||||
activeIds.push(next);
|
||||
}
|
||||
renderGrid();
|
||||
}
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
function renderGrid() {
|
||||
const grid = document.getElementById('grid-view');
|
||||
grid.innerHTML = '';
|
||||
grid.classList.add('visible');
|
||||
activeIds.forEach(id => {
|
||||
const src = document.querySelector(`#single-view .treatment[data-id="${id}"]`);
|
||||
if (src) {
|
||||
const clone = src.cloneNode(true);
|
||||
clone.classList.add('visible');
|
||||
grid.appendChild(clone);
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -626,10 +626,7 @@ async fn execute_run(state: Arc<AppState>, run_id: String) {
|
|||
github_app: None,
|
||||
git_author: state.git_author.clone(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: true,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: fabro_workflows::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1244,7 +1244,6 @@ pub async fn run_command(
|
|||
.as_ref()
|
||||
.map(|c| c.checkpoint.exclude_globs.clone())
|
||||
.unwrap_or_default();
|
||||
let pr_cfg = run_cfg.as_ref().and_then(|c| c.pull_request.as_ref());
|
||||
let config = RunConfig {
|
||||
run_dir: run_dir.clone(),
|
||||
cancel_token: None,
|
||||
|
|
@ -1269,10 +1268,11 @@ pub async fn run_command(
|
|||
github_app: github_app.clone(),
|
||||
git_author,
|
||||
base_branch: detected_base_branch.or(remote_base_branch),
|
||||
pull_request_enabled: pr_cfg.is_some_and(|p| p.enabled),
|
||||
pull_request_draft: pr_cfg.is_none_or(|p| p.draft) && !pr_cfg.is_some_and(|p| p.auto_merge),
|
||||
pull_request_auto_merge: pr_cfg.is_some_and(|p| p.auto_merge),
|
||||
pull_request_merge_strategy: pr_cfg.map(|p| p.merge_strategy).unwrap_or_default(),
|
||||
pull_request: run_cfg
|
||||
.as_ref()
|
||||
.and_then(|c| c.pull_request.as_ref())
|
||||
.filter(|p| p.enabled)
|
||||
.cloned(),
|
||||
asset_globs: run_cfg
|
||||
.as_ref()
|
||||
.and_then(|c| c.assets.as_ref())
|
||||
|
|
@ -1418,85 +1418,87 @@ pub async fn run_command(
|
|||
// Auto-create PR on successful completion (skip in dry-run mode)
|
||||
let mut pushed_branch: Option<String> = None;
|
||||
let mut pr_url: Option<String> = None;
|
||||
if !config.pull_request_enabled {
|
||||
debug!("Skipping PR creation: pull_request not enabled in config");
|
||||
} else if dry_run_mode {
|
||||
debug!("Skipping PR creation: dry-run mode");
|
||||
} else if let Err(ref e) = engine_result {
|
||||
debug!(error = %e, "Skipping PR creation: engine returned an error");
|
||||
} else if let Ok(ref outcome) = engine_result {
|
||||
if !matches!(
|
||||
outcome.status,
|
||||
StageStatus::Success | StageStatus::PartialSuccess
|
||||
) {
|
||||
debug!(status = ?outcome.status, "Skipping PR creation: run status is not success");
|
||||
} else {
|
||||
let diff = tokio::fs::read_to_string(run_dir.join("final.patch"))
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
if let (
|
||||
Some(ref base_branch),
|
||||
Some(ref run_branch),
|
||||
Some(ref creds),
|
||||
Some(ref origin),
|
||||
) = (
|
||||
&config.base_branch,
|
||||
&config.run_branch,
|
||||
&github_app,
|
||||
&origin_url,
|
||||
if let Some(ref pr_cfg) = config.pull_request {
|
||||
if dry_run_mode {
|
||||
debug!("Skipping PR creation: dry-run mode");
|
||||
} else if let Err(ref e) = engine_result {
|
||||
debug!(error = %e, "Skipping PR creation: engine returned an error");
|
||||
} else if let Ok(ref outcome) = engine_result {
|
||||
if !matches!(
|
||||
outcome.status,
|
||||
StageStatus::Success | StageStatus::PartialSuccess
|
||||
) {
|
||||
// Run branch was pushed during checkpoint commits;
|
||||
// just record it for the PR creation.
|
||||
if config.git_checkpoint_enabled {
|
||||
pushed_branch = Some(run_branch.clone());
|
||||
}
|
||||
|
||||
let auto_merge = if config.pull_request_auto_merge {
|
||||
Some(crate::pull_request::AutoMergeConfig {
|
||||
merge_strategy: config.pull_request_merge_strategy,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
match crate::pull_request::maybe_open_pull_request(
|
||||
creds,
|
||||
origin,
|
||||
base_branch,
|
||||
run_branch,
|
||||
graph.goal(),
|
||||
&diff,
|
||||
&model,
|
||||
config.pull_request_draft,
|
||||
auto_merge,
|
||||
&run_dir,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(Some(record)) => {
|
||||
emitter.emit(&crate::event::WorkflowRunEvent::PullRequestCreated {
|
||||
pr_url: record.html_url.clone(),
|
||||
pr_number: record.number,
|
||||
draft: config.pull_request_draft,
|
||||
});
|
||||
pr_url = Some(record.html_url.clone());
|
||||
if let Err(e) = record.save(&run_dir.join("pull_request.json")) {
|
||||
tracing::warn!(error = %e, "Failed to save pull_request.json");
|
||||
}
|
||||
debug!(status = ?outcome.status, "Skipping PR creation: run status is not success");
|
||||
} else {
|
||||
let diff = tokio::fs::read_to_string(run_dir.join("final.patch"))
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
if let (
|
||||
Some(ref base_branch),
|
||||
Some(ref run_branch),
|
||||
Some(ref creds),
|
||||
Some(ref origin),
|
||||
) = (
|
||||
&config.base_branch,
|
||||
&config.run_branch,
|
||||
&github_app,
|
||||
&origin_url,
|
||||
) {
|
||||
// Run branch was pushed during checkpoint commits;
|
||||
// just record it for the PR creation.
|
||||
if config.git_checkpoint_enabled {
|
||||
pushed_branch = Some(run_branch.clone());
|
||||
}
|
||||
Ok(None) => {} // empty diff, logged at DEBUG
|
||||
Err(e) => {
|
||||
emitter.emit(&crate::event::WorkflowRunEvent::PullRequestFailed {
|
||||
error: e.to_string(),
|
||||
});
|
||||
eprintln!(
|
||||
"{} PR creation failed: {e}",
|
||||
styles.yellow.apply_to("Warning:")
|
||||
);
|
||||
|
||||
let auto_merge = if pr_cfg.auto_merge {
|
||||
Some(crate::pull_request::AutoMergeConfig {
|
||||
merge_strategy: pr_cfg.merge_strategy,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
match crate::pull_request::maybe_open_pull_request(
|
||||
creds,
|
||||
origin,
|
||||
base_branch,
|
||||
run_branch,
|
||||
graph.goal(),
|
||||
&diff,
|
||||
&model,
|
||||
pr_cfg.draft,
|
||||
auto_merge,
|
||||
&run_dir,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(Some(record)) => {
|
||||
emitter.emit(&crate::event::WorkflowRunEvent::PullRequestCreated {
|
||||
pr_url: record.html_url.clone(),
|
||||
pr_number: record.number,
|
||||
draft: pr_cfg.draft,
|
||||
});
|
||||
pr_url = Some(record.html_url.clone());
|
||||
if let Err(e) = record.save(&run_dir.join("pull_request.json")) {
|
||||
tracing::warn!(error = %e, "Failed to save pull_request.json");
|
||||
}
|
||||
}
|
||||
Ok(None) => {} // empty diff, logged at DEBUG
|
||||
Err(e) => {
|
||||
emitter.emit(&crate::event::WorkflowRunEvent::PullRequestFailed {
|
||||
error: e.to_string(),
|
||||
});
|
||||
eprintln!(
|
||||
"{} PR creation failed: {e}",
|
||||
styles.yellow.apply_to("Warning:")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
debug!("Skipping PR creation: pull_request not enabled in config");
|
||||
}
|
||||
|
||||
let outcome = engine_result?;
|
||||
|
|
@ -1934,10 +1936,7 @@ async fn run_from_branch(
|
|||
github_app: github_app.clone(),
|
||||
git_author,
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ use fabro_git_storage::trailerlink::{self, Trailer};
|
|||
use crate::artifact::{offload_large_values, sync_artifacts_to_env, ArtifactStore};
|
||||
use crate::asset_snapshot;
|
||||
use crate::checkpoint::Checkpoint;
|
||||
use crate::cli::run_config::PullRequestConfig;
|
||||
use crate::condition::evaluate_condition;
|
||||
use crate::context;
|
||||
use crate::context::Context;
|
||||
|
|
@ -857,14 +858,8 @@ pub struct RunConfig {
|
|||
pub git_author: crate::git::GitAuthor,
|
||||
/// Name of the branch the run was started from (for PR base).
|
||||
pub base_branch: Option<String>,
|
||||
/// Whether to auto-create a PR on successful completion.
|
||||
pub pull_request_enabled: bool,
|
||||
/// Whether to create the PR as a draft.
|
||||
pub pull_request_draft: bool,
|
||||
/// Whether to enable GitHub auto-merge on the created PR.
|
||||
pub pull_request_auto_merge: bool,
|
||||
/// Merge strategy for auto-merge (squash, merge, rebase).
|
||||
pub pull_request_merge_strategy: crate::cli::run_config::MergeStrategy,
|
||||
/// Pull request configuration; `None` = disabled.
|
||||
pub pull_request: Option<PullRequestConfig>,
|
||||
/// Glob patterns for asset collection. Empty = no asset collection.
|
||||
pub asset_globs: Vec<String>,
|
||||
/// Workflow directory slug (e.g. "smoke" from `fabro/workflows/smoke/`).
|
||||
|
|
@ -980,26 +975,6 @@ impl WorkflowRunEngine {
|
|||
let _ = self.run_hooks(&hook_ctx, work_dir).await;
|
||||
}
|
||||
|
||||
/// Fire a non-blocking StageRetrying hook.
|
||||
async fn stage_retrying_hook(
|
||||
&self,
|
||||
node: &Node,
|
||||
context: &Context,
|
||||
graph: &Graph,
|
||||
attempt: u32,
|
||||
policy: &RetryPolicy,
|
||||
) {
|
||||
let mut hook_ctx = HookContext::new(
|
||||
HookEvent::StageRetrying,
|
||||
context.run_id(),
|
||||
graph.name.clone(),
|
||||
);
|
||||
hook_ctx.set_node(node);
|
||||
hook_ctx.attempt = Some(usize::try_from(attempt).unwrap_or(usize::MAX));
|
||||
hook_ctx.max_attempts = Some(usize::try_from(policy.max_attempts).unwrap_or(usize::MAX));
|
||||
let _ = self.run_hooks(&hook_ctx, None).await;
|
||||
}
|
||||
|
||||
/// Mirror graph-level attributes into the context.
|
||||
fn mirror_graph_attributes(graph: &Graph, context: &Context) {
|
||||
if !graph.goal().is_empty() {
|
||||
|
|
@ -1149,8 +1124,6 @@ impl WorkflowRunEngine {
|
|||
.unwrap_or(usize::MAX),
|
||||
delay_ms: millis_u64(delay),
|
||||
});
|
||||
self.stage_retrying_hook(node, context, graph, attempt, policy)
|
||||
.await;
|
||||
tokio::time::sleep(delay).await;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1179,8 +1152,6 @@ impl WorkflowRunEngine {
|
|||
.unwrap_or(usize::MAX),
|
||||
delay_ms: millis_u64(delay),
|
||||
});
|
||||
self.stage_retrying_hook(node, context, graph, attempt, policy)
|
||||
.await;
|
||||
tokio::time::sleep(delay).await;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1657,7 +1628,9 @@ impl WorkflowRunEngine {
|
|||
let mut hook_ctx =
|
||||
HookContext::new(HookEvent::StageStart, run_id.clone(), graph.name.clone());
|
||||
hook_ctx.cwd = hook_work_dir.as_ref().map(|p| p.display().to_string());
|
||||
hook_ctx.set_node(node);
|
||||
hook_ctx.node_id = Some(node.id.clone());
|
||||
hook_ctx.node_label = Some(node.label().to_string());
|
||||
hook_ctx.handler_type = node.handler_type().map(String::from);
|
||||
hook_ctx.attempt = Some(1);
|
||||
hook_ctx.max_attempts =
|
||||
Some(usize::try_from(retry_policy.max_attempts).unwrap_or(usize::MAX));
|
||||
|
|
@ -1793,7 +1766,9 @@ impl WorkflowRunEngine {
|
|||
run_id.clone(),
|
||||
graph.name.clone(),
|
||||
);
|
||||
hook_ctx.set_node(node);
|
||||
hook_ctx.node_id = Some(node.id.clone());
|
||||
hook_ctx.node_label = Some(node.label().to_string());
|
||||
hook_ctx.handler_type = node.handler_type().map(String::from);
|
||||
hook_ctx.status = Some("fail".into());
|
||||
hook_ctx.failure_reason = outcome.failure_reason().map(String::from);
|
||||
let _ = self.run_hooks(&hook_ctx, hook_work_dir.as_deref()).await;
|
||||
|
|
@ -1825,7 +1800,9 @@ impl WorkflowRunEngine {
|
|||
run_id.clone(),
|
||||
graph.name.clone(),
|
||||
);
|
||||
hook_ctx.set_node(node);
|
||||
hook_ctx.node_id = Some(node.id.clone());
|
||||
hook_ctx.node_label = Some(node.label().to_string());
|
||||
hook_ctx.handler_type = node.handler_type().map(String::from);
|
||||
hook_ctx.status = Some(outcome.status.to_string());
|
||||
let _ = self.run_hooks(&hook_ctx, hook_work_dir.as_deref()).await;
|
||||
}
|
||||
|
|
@ -3047,10 +3024,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -3079,10 +3053,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -3119,10 +3090,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -3155,10 +3123,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -3187,10 +3152,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -3232,10 +3194,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -3301,10 +3260,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -3397,10 +3353,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -3436,10 +3389,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -3470,10 +3420,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -3504,10 +3451,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -3542,10 +3486,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -3708,10 +3649,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -3757,10 +3695,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -3824,10 +3759,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -3894,10 +3826,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -3968,10 +3897,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -4031,10 +3957,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -4095,10 +4018,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -4134,10 +4054,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -4169,10 +4086,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -4203,10 +4117,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -4250,10 +4161,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -4334,10 +4242,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -4371,10 +4276,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -4410,10 +4312,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -4454,10 +4353,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -4496,10 +4392,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -4535,10 +4428,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -4635,10 +4525,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -4850,10 +4737,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -4892,10 +4776,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -4941,10 +4822,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -5030,10 +4908,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -5130,10 +5005,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -5207,10 +5079,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -5271,10 +5140,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -5336,10 +5202,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -5497,10 +5360,7 @@ mod tests {
|
|||
github_app: None,
|
||||
git_author: crate::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -156,10 +156,7 @@ impl Handler for SubWorkflowHandler {
|
|||
.map(|gs| gs.git_author.clone())
|
||||
.unwrap_or_default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: true,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: crate::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -403,10 +403,7 @@ async fn daytona_pipeline_artifact_offload_and_sync() {
|
|||
github_app: None,
|
||||
git_author: fabro_workflows::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: fabro_workflows::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -603,10 +600,7 @@ async fn daytona_git_checkpoint_remote_emits_events() {
|
|||
github_app: None,
|
||||
git_author: fabro_workflows::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: fabro_workflows::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -794,10 +788,7 @@ async fn daytona_parallel_git_branching_e2e() {
|
|||
github_app: None,
|
||||
git_author: fabro_workflows::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: fabro_workflows::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -1176,10 +1167,7 @@ async fn daytona_git_checkpoint_with_shadow_branch() {
|
|||
github_app: None,
|
||||
git_author: fabro_workflows::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: fabro_workflows::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -1321,10 +1309,7 @@ async fn daytona_asset_collection() {
|
|||
github_app: None,
|
||||
git_author: fabro_workflows::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: fabro_workflows::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
@ -1581,10 +1566,7 @@ async fn daytona_git_push_run_branch_to_origin() {
|
|||
github_app: None,
|
||||
git_author: fabro_workflows::git::GitAuthor::default(),
|
||||
base_branch: None,
|
||||
pull_request_enabled: false,
|
||||
pull_request_draft: false,
|
||||
pull_request_auto_merge: false,
|
||||
pull_request_merge_strategy: fabro_workflows::cli::run_config::MergeStrategy::Squash,
|
||||
pull_request: None,
|
||||
asset_globs: Vec::new(),
|
||||
workflow_slug: None,
|
||||
};
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue