Skip to content
prod 352bb92
Browse

4 · Initialize the repository

Objective — expand the bootstrap git from Create the project into the full import repo: merge Code & repository setup ignore rules, set identity, wire develop, and lock down per-directory storage ignores — without re-running git init if .git/ already exists.

Steps at a glance:

  1. Set session variables — Export your project’s values once so every command here (and on the next pages) is copy-paste safe.
  2. Merge .gitignore (bootstrap → Code & repository setup) — If Create the project ran, keep its anchored patterns (/vendor/, /_source/, !.env.tpl when using 1Password, .vscode negation from C2).
  3. Initialize or confirm git on developdevelop and the frozen author/vX.X.X baseline already exist from AI dev environment setup. Commit & freeze pushes them — it does not recreate the import commit.
  4. Lock down storage ignores — Laravel’s storage/ subtree must keep its folders in git but ignore their contents. Backfill any missing per-directory .gitignores.
  5. Record the vendor’s installer-marker mechanism — Vendors differ in how they flag “install complete.” Record yours once so deploy excludes and the first-install caution stay accurate per project.

The single most important ordering rule: .gitignore before the first commit that could track secrets or vendor/. Create the project already ran bootstrap git init, committed the pristine vendor baseline on author/v* + tag, and set develop — this page merges Code & repository setup patterns (remote prep, storage subtree, vault paths) without recreating the import. If you somehow skipped Create the project, write .gitignore first, then git init, then run pristine baseline commit before continuing.

Export your project’s values once so every command here (and on the next pages) is copy-paste safe. Pull them from your Zaj-PROJECT.

  1. Export the project variables.

    Terminal window
    export PROJECT_NAME="<project>"
    export VERSION="x.y.z" # replace with the vendor's semver
    export GITHUB_REPO="git@github.com:<your-org>/<project>.git"
    export GIT_USERNAME="Your Name"
    export GIT_EMAIL="<you>@users.noreply.github.com"
    echo "Project: $PROJECT_NAME · Version: $VERSION · Repo: $GITHUB_REPO"
    # Expected: the echoed line shows your real project / version / repo values
    • ✅ The echo prints your actual project, version, and repo — no <placeholder> left.

2. Merge .gitignore (bootstrap → Code & repository setup)

Section titled “2. Merge .gitignore (bootstrap → Code & repository setup)”

If Create the project ran, keep its anchored patterns (/vendor/, /_source/, !.env.tpl when using 1Password, .vscode negation from C2). Add or reconcile the lines below — do not replace the whole file blindly. The bootstrap block lives on Create the project §4; this page only adds Phase-2 deltas.

Write or merge the ignore file so the very next git status stays clean.

flowchart LR
A[".gitignore<br/>merged / written"] --> B{"git init<br/>already?"}
B -->|no| C["git init"]
B -->|yes| D["skip init"]
C --> E["git branch -M develop"]
D --> E
E --> F["git config<br/>user.name / user.email"]
  1. Write a baseline .gitignore for a CodeCanyon Laravel app.

    .gitignore
    # Dependencies
    /vendor/
    /node_modules/
    # Secrets (never commit)
    .env
    .env.*
    !.env.example
    !.env.tpl
    # Laravel generated
    /storage/*.key
    /bootstrap/cache/*.php
    # Installer "complete" marker — per-environment runtime state (like .env): gitignored so it is
    # never COMMITTED. It SHOULD exist on each installed environment (created by that env's own install)
    # and persists on the server via the shared storage/ dir — do NOT delete it on deploy/update.
    # The ONLY hazard is the FIRST install: a brand-new server must never receive a pre-made marker,
    # or its installer is skipped. (Replace with your vendor's marker — see step 5.)
    /storage/installed
    # Per-environment public symlinks — recreated by `php artisan storage:link` (and the module
    # `packages` link, for in-tree module apps); never commit. CodeCanyon vendors often ship
    # public/storage as a TRACKED absolute symlink to a server path (/var/www/...) — dead on every other env.
    /public/storage
    /public/packages
    # Archive — NEVER in git (AI dev environment bootstrap)
    /_source/
    # OS & IDE — .vscode/*.json committed at C2 (machine setup); keep negation if present
    .DS_Store
    /.idea/
    /.vscode/*
    !/.vscode/extensions.json
    !/.vscode/settings.json
    !/.vscode/launch.json
    # Logs & testing
    *.log
    .phpunit.result.cache
    # CodeCanyon ZIPs
    *.zip
    # Agent/browser automation state (can contain cookies, auth headers, PII)
    /.playwright-mcp/*
    !/.playwright-mcp/.gitkeep
    /.browser-mcp/
    /test-results/
    /playwright-report/
    # Build — comment out the next line if you use the Build-Locally strategy
    # /public/build/
    # Project vault (credentials)
    /Admin-Local/1-Project/2-Vault/
    • .gitignore exists at the repo root before any git command runs.
  2. Keep the Playwright MCP folder present but empty (edit-spec M5 — tracked placeholder, ignored session state).

    Terminal window
    mkdir -p .playwright-mcp
    cat > .playwright-mcp/.gitkeep << 'EOF'
    # Playwright MCP session state lives here at runtime.
    # Root .gitignore ignores everything except this file so the folder exists in git
    # without committing cookies, auth headers, or other browser automation artifacts.
    EOF
    git check-ignore .playwright-mcp/session.json && echo "✅ browser state ignored"
    # Expected: ✅ browser state ignored
    • ✅ Only .playwright-mcp/.gitkeep is eligible for git; generated browser state is ignored.
  3. Confirm the installer marker is ignored — but never delete it. The vendor’s “install complete” marker is per-environment runtime state (the same category as .env): it must stay out of git, yet it should exist on each installed environment and persist on the server. Verify it is ignored and don’t stage or remove it.

    Terminal window
    # Default Laravel installer marker. If the vendor uses a different one, swap the path
    # (record it in step 5) — common variants: storage/installed, .installed, public/install.lock
    MARKER="storage/installed"
    git check-ignore -q "$MARKER" && echo "✅ $MARKER ignored (never committed)" \
    || echo "❌ $MARKER NOT ignored — add it to .gitignore before staging"
    # If the marker is already TRACKED from the vendor import, stop tracking it WITHOUT deleting it.
    if git ls-files --error-unmatch "$MARKER" >/dev/null 2>&1; then
    git rm --cached --quiet "$MARKER" && echo "⚠️ untracked $MARKER (file kept on disk)"
    else
    echo "✅ $MARKER not tracked"
    fi
    # Expected: marker ignored and not tracked; the file on disk (if present) is left in place
    • ✅ The marker is git-ignored and not tracked, and the on-disk file (if any) is untouchedgit rm --cached only stops tracking; it does not delete.
  4. Untrack the per-environment public symlinks — they are recreated per environment, never committed. public/storage (and public/packages for in-tree module apps like WorkDo) are per-environment symlinks: they belong to whichever machine ran php artisan storage:link / the packages link, not to git. CodeCanyon vendors frequently ship public/storage tracked as an absolute symlink to their server path (/var/www/html/.../storage/app/public) — dead on every other environment, so all /storage/* assets 403/404 until relinked. Stop tracking any shipped symlink without deleting it; it is recreated in local development (Phase 3).

    Terminal window
    # Stop tracking the per-env symlinks if the vendor shipped them tracked (file kept on disk).
    for link in public/storage public/packages; do
    if git ls-files --error-unmatch "$link" >/dev/null 2>&1; then
    git rm --cached --quiet "$link" && echo "⚠️ untracked $link (recreated per-env in Phase 3)"
    else
    echo "✅ $link not tracked"
    fi
    done
    # Both must be ignored so a future relink/storage:link never re-stages them.
    git check-ignore public/storage public/packages
    # Expected: both paths echoed back (both ignored); neither tracked. A fresh clone has
    # NEITHER symlink until Phase 3 recreates them:
    # php artisan storage:link # → public/storage
    # cd public && ln -s ../packages packages # → public/packages (in-tree module apps)
    • public/storage and public/packages are ignored and not tracked; both are recreated per environment in Phase 3, never committed.

You ignore vendor/ so it never bloats history — but you do not delete the shipped tree (see Extract & snapshot).

  1. Phase 1 prerequisite gate — if any symptom below is true, stop and complete Create the project before continuing:

    SymptomFix
    No author/v* branchRun pristine baseline commit
    No author-v* tagSame — baseline step creates both
    Bootstrap .gitignore missing /_source/Re-run §4 bootstrap gitignore
    On main instead of developgit branch -M develop after init
    Terminal window
    git branch --list 'author/*'
    git tag --list 'author-*'
    grep -q '^/_source/' .gitignore && echo "✅ _source anchored" || echo "❌ fix bootstrap gitignore"
    # Expected: author branch + tag listed; _source anchored
    • ✅ Phase 1 baseline artifacts exist — or you went back to Create the project.
  2. Init only if needed, confirm develop, set identity — do not delete author/v* branches.

    Terminal window
    if [ ! -d .git ]; then git init; fi
    git branch --show-current # expect develop after AI dev environment setup
    git branch -M develop 2>/dev/null || true # no-op if already develop
    git config user.name "$GIT_USERNAME"
    git config user.email "$GIT_EMAIL"
    git branch --list 'author/*'
    # Expected: develop current; author/vX.X.X still present from Create the project baseline
    • git branch --show-current prints develop; author/v* branch still listed; user.name/user.email are set.

develop and the frozen author/vX.X.X baseline already exist from AI dev environment setup. Commit & freeze pushes them — it does not recreate the import commit.

Laravel’s storage/ subtree must keep its folders in git but ignore their contents. Backfill any missing per-directory .gitignores.

  1. Backfill the per-directory storage ignores.

    Terminal window
    for dir in storage/app storage/app/public storage/framework \
    storage/framework/cache storage/framework/sessions \
    storage/framework/views storage/logs; do
    [ -f "$dir/.gitignore" ] || { mkdir -p "$dir"; printf "*\n!.gitignore\n" > "$dir/.gitignore"; }
    done
    # Expected: each storage subdir ends up with a "* / !.gitignore" ignore file
    • ✅ Every storage/** directory carries a .gitignore.
  2. Confirm the root ignore catches the big three before you stage anything.

    Terminal window
    grep -E "^/vendor|^/node_modules|^\.env$" .gitignore # all three should print
    # Expected: three matching lines (/vendor, /node_modules, .env)
    • ✅ All three patterns print, and git status shows no vendor/, node_modules/, or .env.
  3. Prove lock files are not ignored.

    Terminal window
    for f in composer.lock package-lock.json pnpm-lock.yaml yarn.lock; do
    test -e "$f" || continue
    git check-ignore -q "$f" && echo "❌ ignored: $f" || echo "✅ tracked-capable: $f"
    done
    # Expected: every existing lock file is tracked-capable
    • ✅ Lock files remain commit-capable so dependency versions are reproducible.
  4. Match /public/build and run the .gitignore sweep.

    Terminal window
    if grep -q '^/public/build/' .gitignore; then
    echo "Strategy: build-on-server or CI artifact upload"
    else
    test -f public/build/manifest.json && echo "Strategy: build locally and commit public/build" \
    || echo "Strategy: build locally (public/build not present yet)"
    fi
    grep -q "^composer.lock" .gitignore && echo "❌ REMOVE composer.lock from .gitignore" || echo "✅ composer.lock not ignored"
    grep -q "^package-lock.json" .gitignore && echo "❌ REMOVE package-lock.json from .gitignore" || echo "✅ package-lock.json not ignored"
    # Expected: strategy line matches Zaj-PROJECT.md; lock files not ignored
    • .gitignore and the deploy asset strategy agree; lock files stay tracked per Branch strategy §4.

5. Record the vendor’s installer-marker mechanism

Section titled “5. Record the vendor’s installer-marker mechanism”

Vendors differ in how they flag “install complete.” Record yours once so deploy excludes and the first-install caution stay accurate per project.

  1. Find the marker your vendor writes. Grep the vendor tree for where the installer creates its “done” flag.

    Terminal window
    # Most CodeCanyon Laravel installers write a file once /install finishes.
    grep -rIn --include='*.php' -E "storage_path\('installed'\)|'installed'|install(ed)?\.lock|InstallController|CheckInstallation" \
    app/ routes/ vendor/ 2>/dev/null | head -20
    # Expected: the path the installer writes (e.g. storage_path('installed')) + the
    # middleware that redirects to /install when the marker is absent
    • ✅ You can name the exact marker path and the middleware that gates /install.
  2. Record it in your project notes so the next phases reference the real path, not the default.

    Terminal window
    cat >> Admin-Local/1-Project/3-Templates/installer-marker.md << EOF
    # Installer marker — $PROJECT_NAME (vendor $VERSION)
    - Marker path: storage/installed # ← replace with the path grep found
    - Gate middleware: CheckInstallation # ← replace with the real class
    - Rule: gitignored (never committed); created by each env's own install;
    lives in shared storage/ on the server; deploy-EXCLUDE on a fresh server.
    EOF
    echo "✅ recorded installer marker for $PROJECT_NAME"
    # Expected: a per-project note capturing the marker path + gate so Phase 4/5 deploy excludes stay correct
    • ✅ The marker path and gate are recorded; if it differs from storage/installed, update the .gitignore line and the step-2 MARKER variable to match.

Do not mark this step done until every box below is checked.

  • 🤖 Session variables exportedPROJECT_NAME, VERSION, GITHUB_REPO, identity.
  • 🤖 .gitignore merged — AI dev environment bootstrap anchors preserved; Code & repository setup patterns added; lock files not ignored.
  • 🤖 Tree cleangit status shows no vendor/, node_modules/, or .env.
  • 🤖 On developuser.name / user.email configured.
  • 🤖 Storage ignores in place — each storage/** directory carries a .gitignore.
  • 🤖 Installer marker handled — gitignored and not tracked (git rm --cached only, on-disk file kept), per-env symlinks (/public/storage, /public/packages) ignored, and the vendor’s marker path recorded in Admin-Local/1-Project/3-Templates/installer-marker.md.