> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tablepro.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Building

> Development builds, release builds, DMG packaging, code signing, and CI/CD

# Building TablePro

## Development Builds

### Xcode

* `Cmd+R` to build and run
* `Cmd+B` to build only
* Scheme: **TablePro**, Destination: **My Mac**

### Command Line

```bash theme={null}
xcodebuild -project TablePro.xcodeproj \
    -scheme TablePro \
    -configuration Debug \
    build \
    -skipPackagePluginValidation
```

Build and run:

```bash theme={null}
xcodebuild -project TablePro.xcodeproj \
    -scheme TablePro \
    -configuration Debug \
    build \
    -skipPackagePluginValidation && open build/Debug/TablePro.app
```

<Note>
  `-skipPackagePluginValidation` is required. CodeEditSourceEditor bundles a SwiftLint plugin that triggers Xcode's plugin validation on CLI builds.
</Note>

## Release Builds

```bash theme={null}
# Apple Silicon
scripts/build-release.sh arm64

# Intel
scripts/build-release.sh x86_64

# Both architectures
scripts/build-release.sh both
```

Output:

```
build/Release/TablePro-arm64.app
build/Release/TablePro-x86_64.app
```

The build script handles architecture slicing from universal static libraries automatically.

## Native Libraries

Static `.a` files (libmariadb, libpq, libfreetds, etc.) are hosted on a GitHub Release (tag `libs-v1`). They are not in git.

```bash theme={null}
# Download (skips if already present)
scripts/download-libs.sh

# Force re-download
scripts/download-libs.sh --force
```

### Updating Libraries (Maintainers)

When updating a static library:

```bash theme={null}
# Regenerate checksums
shasum -a 256 Libs/*.a > Libs/checksums.sha256

# Create and upload archive
tar czf /tmp/tablepro-libs-v1.tar.gz -C Libs .
gh release upload libs-v1 /tmp/tablepro-libs-v1.tar.gz --clobber --repo TableProApp/TablePro

# Commit checksum changes
git add Libs/checksums.sha256 && git commit -m "build: update static library checksums"
```

## Creating DMG

Build the release first, then package:

```bash theme={null}
scripts/build-release.sh arm64
scripts/create-dmg.sh arm64
```

Output:

```
build/Release/TablePro-arm64.dmg
build/Release/TablePro-x86_64.dmg
```

## Code Signing

### Development

Unsigned by default. No certificate needed for local testing.

### Distribution

```bash theme={null}
# Sign
codesign --force --deep --sign "Developer ID Application: Your Name (TEAM_ID)" \
    build/Release/TablePro-arm64.app

# Verify
codesign --verify --verbose build/Release/TablePro-arm64.app
```

### Notarization

```bash theme={null}
# Create ZIP
ditto -c -k --keepParent build/Release/TablePro-arm64.app TablePro.zip

# Submit
xcrun notarytool submit TablePro.zip \
    --apple-id "your@email.com" \
    --team-id "TEAM_ID" \
    --password "app-specific-password" \
    --wait

# Staple
xcrun stapler staple build/Release/TablePro-arm64.app
```

## Clean Build

| Method  | Command                                                         |
| ------- | --------------------------------------------------------------- |
| Xcode   | `Cmd+Shift+K`                                                   |
| CLI     | `xcodebuild -project TablePro.xcodeproj -scheme TablePro clean` |
| Nuclear | `rm -rf ~/Library/Developer/Xcode/DerivedData`                  |

## CI/CD

### App Releases

GitHub Actions workflow: `.github/workflows/build.yml`

Triggered by `v*` tags (e.g., `v0.18.0`).

Pipeline: lint -> build arm64 -> build x86\_64 -> release (DMG + ZIP + Sparkle signatures)

Release notes are auto-extracted from `CHANGELOG.md`.

### Plugin Releases

Workflow: `.github/workflows/build-plugin.yml`

Triggered by `plugin-*-v*` tags (e.g., `plugin-oracle-v1.0.0`).

<Warning>
  GitHub only fires one workflow per multi-tag push. Push plugin tags individually, or use `workflow_dispatch` with comma-separated tags for bulk releases.
</Warning>

## Build Sizes

| Build          | Size     |
| -------------- | -------- |
| Debug app      | \~15 MB  |
| Release app    | \~10 MB  |
| DMG (per arch) | \~3.5 MB |
