-
Notifications
You must be signed in to change notification settings - Fork 9
feat(ci): add cross-platform final build checks #279
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| --- | ||
| "@prover-coder-ai/docker-git": patch | ||
| "@prover-coder-ai/docker-git-session-sync": patch | ||
| --- | ||
|
|
||
| Add portable launch/build scripts and CI final-build verification across Linux, macOS, and Windows. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| name: Final Build | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| pull_request: | ||
| branches: [main] | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| final-build: | ||
| name: Final build (${{ matrix.os }}) | ||
| runs-on: ${{ matrix.os }} | ||
| timeout-minutes: 20 | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| os: [ubuntu-latest, macos-latest, windows-latest] | ||
| steps: | ||
| - uses: actions/checkout@v6 | ||
| - name: Install dependencies | ||
| uses: ./.github/actions/setup | ||
| with: | ||
| bun-version: 1.3.11 | ||
| node-version: 24.14.0 | ||
| - name: Build final workspace packages | ||
| run: bun run build | ||
| - name: Verify docker-git CLI starts | ||
| run: bun ./packages/app/dist/src/docker-git/main.js --help | ||
| - name: Verify session sync CLI starts | ||
| run: bun ./packages/docker-git-session-sync/dist/docker-git-session-sync.js --help | ||
| - name: Prepare package artifacts directory | ||
| run: | | ||
| node -e "require('node:fs').mkdirSync('artifacts', { recursive: true })" | ||
| - name: Pack docker-git package | ||
| working-directory: packages/app | ||
| run: bun pm pack --quiet --ignore-scripts --destination ../../artifacts | ||
| - name: Pack session sync package | ||
| working-directory: packages/docker-git-session-sync | ||
| run: bun pm pack --quiet --ignore-scripts --destination ../../artifacts | ||
| - name: Upload final build artifacts | ||
| uses: actions/upload-artifact@v7 | ||
| with: | ||
| name: final-build-${{ matrix.os }} | ||
| path: artifacts/*.tgz | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| import { describe, expect, it } from "@effect/vitest" | ||
|
|
||
| import rootPackage from "../../../../package.json" with { type: "json" } | ||
| import sessionSyncPackage from "../../../docker-git-session-sync/package.json" with { type: "json" } | ||
| import appPackage from "../../package.json" with { type: "json" } | ||
|
|
||
| const launchScripts: ReadonlyArray<Readonly<{ packageName: string; scriptName: string; script: string }>> = [ | ||
| { packageName: "workspace", scriptName: "clone", script: rootPackage.scripts.clone }, | ||
| { packageName: "workspace", scriptName: "open", script: rootPackage.scripts.open }, | ||
| { packageName: "workspace", scriptName: "docker-git", script: rootPackage.scripts["docker-git"] }, | ||
| { packageName: "workspace", scriptName: "list", script: rootPackage.scripts.list }, | ||
| { packageName: "workspace", scriptName: "start", script: rootPackage.scripts.start }, | ||
| { packageName: "@prover-coder-ai/docker-git", scriptName: "clone", script: appPackage.scripts.clone }, | ||
| { packageName: "@prover-coder-ai/docker-git", scriptName: "open", script: appPackage.scripts.open }, | ||
| { | ||
| packageName: "@prover-coder-ai/docker-git", | ||
| scriptName: "docker-git", | ||
| script: appPackage.scripts["docker-git"] | ||
| }, | ||
| { packageName: "@prover-coder-ai/docker-git", scriptName: "list", script: appPackage.scripts.list }, | ||
| { packageName: "@prover-coder-ai/docker-git", scriptName: "start", script: appPackage.scripts.start } | ||
| ] | ||
|
|
||
| describe("package scripts cross-platform contract", () => { | ||
| it("keeps user-facing launch scripts independent from bash", () => { | ||
| for (const entry of launchScripts) { | ||
| expect(entry.script, `${entry.packageName}:${entry.scriptName}`).not.toMatch(/\bbash(?:\.exe)?\b/u) | ||
| } | ||
| }) | ||
|
|
||
| it("keeps final package build independent from raw chmod", () => { | ||
| expect(sessionSyncPackage.scripts.build).not.toMatch(/\bchmod\s+/u) | ||
| }) | ||
| }) | ||
|
Comment on lines
+24
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win Add property-based assertions for script invariants. This test is table-driven only; please add Proposed direction+import fc from "fast-check"
...
+ it("bash-free launch scripts hold for all declared launch entries", () => {
+ fc.assert(
+ fc.property(fc.constantFrom(...launchScripts), (entry) => {
+ expect(entry.script).not.toMatch(/\bbash(?:\.exe)?\b/u)
+ })
+ )
+ })As per coding guidelines "**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants." 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -74,6 +74,17 @@ describe("renderDockerfile", () => { | |
| }) | ||
| }) | ||
|
|
||
| describe("renderEntrypoint clone cache", () => { | ||
| it("refreshes mirrors without broad remote refs", () => { | ||
| const entrypoint = renderEntrypoint(makeTemplateConfig()) | ||
|
|
||
| expect(entrypoint).toContain("git --git-dir '$CACHE_REPO_DIR' fetch") | ||
| expect(entrypoint).toContain("'+refs/heads/*:refs/heads/*'") | ||
| expect(entrypoint).toContain("'+refs/tags/*:refs/tags/*'") | ||
| expect(entrypoint).not.toContain("'+refs/*:refs/*'") | ||
| }) | ||
| }) | ||
|
Comment on lines
+77
to
+86
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: Recommended way: use fast-check through the dedicated Vitest connector package Citations:
🏁 Script executed: # First, locate the test file and examine its content
find . -path "*/packages/lib/tests/core/templates.test.ts" -type fRepository: ProverCoderAI/docker-git Length of output: 112 🏁 Script executed: # Check if file exists using git ls-files as fallback
git ls-files | grep -E "templates\.test\.ts"Repository: ProverCoderAI/docker-git Length of output: 110 🏁 Script executed: # Search for templates test file more broadly
fd "templates.test.ts" --type fRepository: ProverCoderAI/docker-git Length of output: 110 🏁 Script executed: # Look for the renderEntrypoint function
rg "renderEntrypoint" -t ts -t tsx -A 5 --max-count 20Repository: ProverCoderAI/docker-git Length of output: 96 🏁 Script executed: # Check project dependencies for Vitest and fast-check
cat package.json | jq '.devDependencies | to_entries[] | select(.key | test("vitest|fast-check")) | "\(.key): \(.value)"'Repository: ProverCoderAI/docker-git Length of output: 50 🏁 Script executed: # Search for existing fast-check usage in test files
fd ".test.ts" -o ".spec.ts" --type f -x rg "fast-check|fc\." {} --max-count 5Repository: ProverCoderAI/docker-git Length of output: 204 🏁 Script executed: # Read the test file
cat -n packages/lib/tests/core/templates.test.ts | head -100Repository: ProverCoderAI/docker-git Length of output: 5439 🏁 Script executed: # Search for renderEntrypoint function definition
rg "function renderEntrypoint|const renderEntrypoint|export.*renderEntrypoint" -A 10Repository: ProverCoderAI/docker-git Length of output: 50380 🏁 Script executed: # Check package.json for dependencies
cat package.json | head -100Repository: ProverCoderAI/docker-git Length of output: 4503 🏁 Script executed: # Look for fast-check imports or usage
rg "from.*fast-check|import.*fc\." --type tsRepository: ProverCoderAI/docker-git Length of output: 50 🏁 Script executed: # Find renderCloneBody and git ref generation logic
rg "renderCloneBody|git.*fetch.*refs|refs/heads|refs/tags" -A 3 -B 2Repository: ProverCoderAI/docker-git Length of output: 17230 🏁 Script executed: # Check if fast-check is mentioned anywhere in the codebase (even if not installed)
rg "fast-check|fc\." --type ts --max-count 10Repository: ProverCoderAI/docker-git Length of output: 50 🏁 Script executed: # Look at the package.json for lib package specifically
cat packages/lib/package.json | head -150Repository: ProverCoderAI/docker-git Length of output: 3283 Add explicit negative assertions for merge-request and pull-request refs. The test validates the clone-cache refspec invariant (documented in tasks.ts) but is incomplete. Add 🤖 Prompt for AI Agents |
||
|
|
||
| describe("renderEntrypointGitHooks", () => { | ||
| it("installs pre-push protection checks and a global git post-push runtime", () => { | ||
| const hooks = renderEntrypointGitHooks() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| #!/usr/bin/env bun | ||
|
|
||
| import { chmodSync } from "node:fs" | ||
| import { resolve } from "node:path" | ||
|
|
||
| // CHANGE: centralize executable-bit handling for generated CLI files. | ||
| // WHY: POSIX chmod is not available on Windows, while Linux/macOS package builds require executable bins. | ||
| // QUOTE(TZ): "run conveniently on Windows and Linux" | ||
| // REF: issue-278 | ||
| // SOURCE: n/a | ||
| // FORMAT THEOREM: forall p in Paths: platform=win32 -> no_posix_chmod(p), platform!=win32 -> executable(p) | ||
| // PURITY: SHELL | ||
| // EFFECT: filesystem metadata update | ||
| // INVARIANT: missing target argument exits non-zero; Windows builds do not invoke POSIX chmod. | ||
| // COMPLEXITY: O(1)/O(1) | ||
| const target = process.argv[2] | ||
|
|
||
| if (target === undefined || target.length === 0) { | ||
| process.stderr.write("Usage: mark-executable <path>\n") | ||
| process.exitCode = 1 | ||
| } else if (process.platform !== "win32") { | ||
| chmodSync(resolve(process.cwd(), target), 0o755) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Final Build is missing the requested browser/UI clone smoke check.
The workflow currently validates CLI startup only. It does not cover the reviewer-requested runtime path: browser launch and cloning via UI/menu, so the PR acceptance criteria in discussion remain partially unverified.
🤖 Prompt for AI Agents