refresh: rebuild a gh-pages venture in place, from its own tools/build.sh #67
No files matched your search
@@ -0,0 +1,95 @@
|
||||
name: refresh
|
||||
# Refresh a venture that lives on gh-pages and makes some of its own files (fonts, art, screenshots, generated
|
||||
# code): run ventures/<slug>/tools/build.sh on the runner, in place, then commit what changed to gh-pages in one
|
||||
# commit and ask Teahub pages to pull. Actions -> refresh -> Run workflow.
|
||||
# `from` takes the venture's folder from another branch (say, a rework in progress), so the new version is built and
|
||||
# lands whole instead of file by file. The build runs in a checkout without credentials; only ventures/<slug>/ comes
|
||||
# back. Chrome for screenshots: CHROME (Playwright's Chromium is installed when the runner has none), with
|
||||
# CHROME_FLAGS for running as root.
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
slug:
|
||||
description: "The venture: ventures/<slug>/ on gh-pages, with a tools/build.sh"
|
||||
required: true
|
||||
type: string
|
||||
from:
|
||||
description: "Branch to take the venture's folder from (empty: gh-pages itself)"
|
||||
required: false
|
||||
type: string
|
||||
permissions:
|
||||
contents: write
|
||||
concurrency:
|
||||
group: venture # the venture loop and seed write gh-pages too: take turns
|
||||
cancel-in-progress: false
|
||||
jobs:
|
||||
refresh:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- name: check the inputs
|
||||
env: # inputs reach the scripts through the environment, never interpolated into them
|
||||
SLUG: ${{ inputs.slug }}
|
||||
FROM: ${{ inputs.from }}
|
||||
run: |
|
||||
printf '%s' "$SLUG" | grep -Eqx '[a-z0-9]([a-z0-9-]{0,40}[a-z0-9])?' || { echo "::error::bad slug: $SLUG"; exit 1; }
|
||||
[ -z "$FROM" ] || printf '%s' "$FROM" | grep -Eqx '[A-Za-z0-9._/-]{1,100}' || { echo "::error::bad branch: $FROM"; exit 1; }
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ inputs.from || 'gh-pages' }}
|
||||
path: work
|
||||
fetch-depth: 1
|
||||
sparse-checkout: ventures/${{ inputs.slug }}
|
||||
persist-credentials: false # the build that runs next must not find a token in .git/config
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
- name: find Chrome, or install Playwright's Chromium
|
||||
run: |
|
||||
set -eu
|
||||
for c in google-chrome google-chrome-stable chromium chromium-browser; do
|
||||
if command -v "$c" >/dev/null 2>&1; then
|
||||
echo "CHROME=$(command -v "$c")" >> "$GITHUB_ENV"; echo "using $(command -v "$c")"; exit 0
|
||||
fi
|
||||
done
|
||||
echo "no Chrome on this runner: installing Playwright's Chromium"
|
||||
npx -y playwright@1.55.0 install --with-deps chromium > /tmp/pw.log 2>&1 || { tail -20 /tmp/pw.log; exit 1; }
|
||||
c=$(find "$HOME/.cache/ms-playwright" -type f -name chrome -path '*chrome-linux*' | head -1)
|
||||
[ -n "$c" ] && [ -x "$c" ] || { echo "::error::no Chromium after the install"; exit 1; }
|
||||
echo "CHROME=$c" >> "$GITHUB_ENV"; echo "using $c"
|
||||
- name: build
|
||||
env:
|
||||
SLUG: ${{ inputs.slug }}
|
||||
CHROME_FLAGS: "--no-sandbox --disable-dev-shm-usage --disable-gpu"
|
||||
run: |
|
||||
set -eu
|
||||
[ -f "work/ventures/$SLUG/tools/build.sh" ] || { echo "::error::ventures/$SLUG has no tools/build.sh"; exit 1; }
|
||||
sh "work/ventures/$SLUG/tools/build.sh"
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
ref: gh-pages
|
||||
path: pages
|
||||
fetch-depth: 1
|
||||
- name: commit what changed
|
||||
env:
|
||||
SLUG: ${{ inputs.slug }}
|
||||
FROM: ${{ inputs.from }}
|
||||
run: |
|
||||
set -eu
|
||||
[ -f "pages/ventures/ventures.json" ] || { echo "::error::no ledger on gh-pages"; exit 1; }
|
||||
rm -rf "pages/ventures/$SLUG"
|
||||
cp -R "work/ventures/$SLUG" "pages/ventures/$SLUG"
|
||||
find "pages/ventures/$SLUG" -name __pycache__ -type d -prune -exec rm -rf {} +
|
||||
cd pages
|
||||
git add --all "ventures/$SLUG"
|
||||
if git diff --cached --quiet; then echo "nothing changed in ventures/$SLUG"; exit 0; fi
|
||||
git diff --cached --stat | tail -25
|
||||
git -c user.name='github-actions[bot]' -c user.email='github-actions[bot]@users.noreply.teahub.xyz' \
|
||||
commit -q -m "ventures: refresh $SLUG${FROM:+ from $FROM}"
|
||||
if ! git push -q origin HEAD:gh-pages; then # gh-pages moved under us: replay this one commit on top
|
||||
git pull -q --rebase origin gh-pages
|
||||
git push -q origin HEAD:gh-pages
|
||||
fi
|
||||
echo "refreshed: ventures/$SLUG -> https://$SLUG.yolopreneur.lol/"
|
||||
- name: tell Teahub pages to pull
|
||||
run: curl -fsS -X POST "https://yolopreneur.lol/_hook/${GITHUB_REPOSITORY}" || echo "pages pulls by itself within five minutes"
|
||||
@@ -9,6 +9,7 @@ A Gitea-native agent factory, running on Teahub prod (teahub.xyz). The Gitea rep
|
||||
- **Venture loop** (`venture.yml`, every 20 min once `TIME_VENTURE=on`): one venture card a day, or one right away from Actions → venture → Run workflow → "Start a new venture now". It scouts the repos that gained the most stars this week; seats pitch; the board votes (Borda, quorum of two); every board seat writes a launch plan (positioning, first users, pricing, channels, 7-day success and kill lines) and one seat synthesizes them into `LAUNCH.md`; the worker builds the product as the page on `gh-pages` (the tool fills the first screen under a slim header with the one signup button; pricing, limits and the why sit below); deterministic checks and headless Chrome (phone and desktop) gate it, with two fix rounds before an andon; GitHub Pages ships it at `/ventures/<slug>/`. Signups go through an issue form (`.github/ISSUE_TEMPLATE/early-access.yml`), each one thanked on its issue; after 7 days the count of distinct people decides: build v2, kill, or watch a week more. The studio index lives at `/ventures/`. Launch posts are drafts for a human; nothing is posted outside the repo.
|
||||
- **Batches** (`TIME_VENTURE_BATCH=3`, or Run workflow → "batch"): one scout pass, a field of pitches, and the board's top k become venture cards in one milestone, built side by side and launched together. A held child gets one batch retry before it's counted dead; a retro compares the cohort once every child is measured.
|
||||
- **Seed** (`seed.yml`, manual): land a venture that was built somewhere else. Give it a slug, the URL of a .tgz whose top folder is that slug (or of its parts, in order) and the .tgz's sha256, plus a name and a one-liner for a new venture. `seed.py` checks the bundle, copies it to `ventures/<slug>/` on `gh-pages` in one commit, adds or refreshes its line in `ventures/ventures.json`, and asks Teahub pages to pull, so it is live at `<slug>.yolopreneur.lol` within the minute. Nothing in the bundle runs.
|
||||
- **Refresh** (`refresh.yml`, manual): for a venture that lives on gh-pages and makes some of its own files (fonts, art, screenshots, generated code). It runs `ventures/<slug>/tools/build.sh` on the runner, in place and without credentials, then commits what changed to gh-pages in one commit and asks Teahub pages to pull. `from` takes the folder from another branch first, so a reworked venture lands whole.
|
||||
- **Backends** (optional, `CLOUDFLARE_API_TOKEN` + `CLOUDFLARE_ACCOUNT_ID`): each venture also gets its own Cloudflare Worker, D1 database and Workers AI, serving its Pages folder at `<slug>.<TIME_VENTURE_DOMAIN>`. The page talks to it through `time.js` (share links that save a creation, a rate-limited small model, and accounts with passkeys: no passwords, no email); every call degrades gracefully, so products still work on Pages alone. Code: `.github/time/cloudflare.py` and `cloudflare/worker.js`.
|
||||
- **Doctor** (`doctor.yml`, manual): runs the tests and checks label, settings, keys and today's spend.
|
||||
- **Update** (`update.yml`, weekly or manual): opens a PR with the latest engine from teahubxyz/time, so every project stays on one Time instead of drifting copies.
|
||||
|
||||
Reference in new issue
Block a user