The local-test-build.sh script provides a completely ephemeral build environment for CSV2Notion Neo. It creates a self-contained build system that doesn't install anything on your system, making it perfect for development, testing, and CI/CD workflows.
- Fully Ephemeral: Everything is contained in project directories
- No System Installation: Downloads standalone CPython into
.build/python/(python-build-standalone) - GitHub Actions Compatible: Poetry, setuptools, and plugin-export pins are intended to match CI/CD (macOS uses standalone Python bootstrap)
- Cross-Platform: Works on macOS (Apple Silicon or Intel)
- Clean Output: Professional logging without emojis
- Flexible Updates: Multiple dependency management options
- Comprehensive Testing: Built-in support for the comprehensive test suite (no Notion credentials required)
- macOS (Apple Silicon or Intel)
- Host tools only:
curlandtar(to download/extract Python into.build/) - No system Python, Homebrew Python, or Poetry install required
# From the project root directory
./scripts/local-test-build.shThis will:
- Download standalone CPython 3.14.5 into
.build/python/(pinned python-build-standalone release) - Install pip 26.1.2 in
.build/python/ - Install setuptools 82.0.1 in
.build/python/ - Install Poetry 2.4.1 in
.build/python/ - Install poetry-plugin-export 1.10.0
- Install project dependencies via Poetry into
.build/venv/ - Install PyInstaller for building
- Build the application
- Output the binary to
test-build/csv2notion_neo
./test-build/csv2notion_neo --help# Normal build
./scripts/local-test-build.sh
# Build and run tests
./scripts/local-test-build.sh --test
# Run comprehensive test suite (96 tests, mocked Notion API)
./scripts/local-test-build.sh --comprehensive-test
# Clean .build/, test-build/, .pytest_cache/ and exit
./scripts/local-test-build.sh --clean# Update poetry.lock file before building
./scripts/local-test-build.sh --update-lock
# Update all dependencies to latest versions
./scripts/local-test-build.sh --update-deps
# Update specific packages
./scripts/local-test-build.sh --update notion-client urllib3
# Only update lock file (no build)
./scripts/local-test-build.sh --lock-only --update requests
# Show outdated packages
./scripts/local-test-build.sh --show-outdated# Show detailed help
./scripts/local-test-build.sh --helpAfter running the script, your project will have:
csv2notion-neo/
├── .build/ # Ephemeral build environment (gitignored)
│ ├── python/ # Standalone CPython + pip + Poetry
│ ├── downloads/ # Cached Python tarball
│ ├── venv/ # Poetry project virtual environment
│ ├── cache/ # Poetry cache
│ ├── pip-cache/ # pip download cache
│ ├── poetry-config/ # Poetry configuration
│ └── poetry-home/ # Poetry application data
├── test-build/ # Build output (gitignored)
│ ├── csv2notion_neo # Final executable binary
│ └── build/ # PyInstaller build artifacts
├── scripts/
│ └── local-test-build.sh # This script
└── ... (other project files)
-
First Time Setup
# Clone the repository git clone https://github.com/TheAcharya/csv2notion-neo.git cd csv2notion-neo # Build the application ./scripts/local-test-build.sh
-
Regular Development
# Make changes to your code # ... # Rebuild ./scripts/local-test-build.sh # Test the changes ./test-build/csv2notion_neo --help
-
Update Dependencies
# Update specific package ./scripts/local-test-build.sh --update notion-client # Update all dependencies ./scripts/local-test-build.sh --update-deps
-
Run Comprehensive Tests
# Validates CLI args and Notion SDK behavior without live API credentials ./scripts/local-test-build.sh --comprehensive-test -
Clean and Rebuild
# Clean everything ./scripts/local-test-build.sh --clean # Fresh build ./scripts/local-test-build.sh
The script is designed to work seamlessly with GitHub Actions. Use the same Poetry, setuptools, and plugin-export versions in workflow env blocks:
# Example GitHub Actions step
- name: Build CSV2Notion Neo
run: |
chmod +x scripts/local-test-build.sh
./scripts/local-test-build.sh
# Example comprehensive test step
- name: Run Comprehensive Tests
run: |
chmod +x scripts/local-test-build.sh
./scripts/local-test-build.sh --comprehensive-testVersion alignment (local script pins; workflows should use matching env values):
| Component | Local script | Suggested CI env |
|---|---|---|
| Python | Standalone 3.14.5 on macOS | 3.14 (BUILD_PYTHON_VERSION) |
| pip | 26.1.2 (bootstrap only) | — |
| Poetry | 2.4.1 | BUILD_POETRY_VERSION |
| setuptools | 82.0.1 | BUILD_SETUPTOOLS_VERSION |
| poetry-plugin-export | 1.10.0 | BUILD_POETRY_PLUGIN_EXPORT_VERSION |
| PyInstaller | latest (Poetry venv at build time) | same pattern as CI binary job |
Local macOS builds download a standalone CPython tarball; CI runners typically use actions/setup-python. Tooling pins (Poetry, setuptools, export plugin) should match.
The --comprehensive-test option runs tests/test_comprehensive.py (96 tests) with mocked Notion API calls—no integration token required.
- CLI validation: 50+ arguments and switches
- Notion SDK adapter tests (mocked
notion_client.Client) - Rate-limit and throttle behavior (
TestNotionRateLimitAndThrottle) - Automatic setup: creates
.build/if missing
./scripts/local-test-build.sh --comprehensive-test- Standalone Python:
.build/python/(python-build-standalone 3.14.5, not system Python) - Project venv:
.build/venv/(Poetry-managed dependencies) - pip: 26.1.2 (pinned bootstrap in
.build/python/) - Setuptools: 82.0.1 (installed before Poetry)
- Poetry: 2.4.1 (installed via pip in
.build/python/) - poetry-plugin-export: 1.10.0
- Dependencies: Managed by Poetry in
.build/venv/
- Binary:
test-build/csv2notion_neo - Size: ~18MB typical on macOS (Python 3.14 one-file bundle; varies by platform)
- Architecture: Native to your system
- Dependencies: Self-contained (no external dependencies)
- Spec File: Uses
csv2notion_neo.specfrom project root - Output Directory:
test-build/ - Build Artifacts:
test-build/build/ - Installation: Installed separately (not in
pyproject.toml)
-
"Missing required host tools"
# curl and tar must be available (standard on macOS) which curl tar -
"Failed to download standalone Python"
# Retry after network check, or clean and rebuild ./scripts/local-test-build.sh --clean ./scripts/local-test-build.sh -
Build fails with PyInstaller errors
# Clean and rebuild ./scripts/local-test-build.sh --clean ./scripts/local-test-build.sh -
Permission denied
# Make script executable chmod +x scripts/local-test-build.sh -
SSL Warning during build
urllib3/__init__.py:35: NotOpenSSLWarning: urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'This warning is normal on macOS when building locally due to different SSL library versions between the build environment and system. It doesn't affect the functionality of the built binary and can be safely ignored.
-
Comprehensive test failures
./scripts/local-test-build.sh --comprehensive-test ls -la .build/ tests/test_comprehensive.py
-
Clean fails on nested Poetry cache
chmod -R u+w .build 2>/dev/null ./scripts/local-test-build.sh --clean
If you encounter issues, you can inspect the build environment:
# Check what's in the build directory
ls -la .build/
# Check the standalone interpreter
.build/python/bin/python3 --version
# Check setuptools installation
.build/python/bin/pip show setuptools
# Check Poetry installation
.build/python/bin/poetry --version
# Check PyInstaller installation
.build/python/bin/poetry run pyinstaller --version
# Run comprehensive tests manually
.build/python/bin/poetry run pytest tests/test_comprehensive.py -v --tb=long# Remove build directories
rm -rf .build/ test-build/ .pytest_cache/
# Or use the script
./scripts/local-test-build.sh --clean.build/- Complete ephemeral environmenttest-build/- Build output and artifacts.pytest_cache/- Pytest cache (when using--clean)dist/- Legacy build output (if exists)build/- Legacy build artifacts (if exists)
- Always run from project root: The script expects
pyproject.tomlin the current directory - Use clean builds: Run
--cleanwhen switching branches, changing Python pins, or after major dependency changes - Test the binary: Always verify
./test-build/csv2notion_neo --helpworks after building - Keep dependencies updated: Use
--show-outdatedto check for updates; prefer--lock-only --update <pkg>for targeted bumps - Run comprehensive tests before releases:
./scripts/local-test-build.sh --comprehensive-test
- Use matching env pins: Align workflow variables with the script configuration (see Version Alignment)
- Clean before build: Run
--cleanin CI when you need a fully fresh environment - Test the output: Verify the built binary in your target environment
- Comprehensive tests in CI: Use
--comprehensive-testfor fast validation without Notion credentials
Pinned at the top of scripts/local-test-build.sh:
BUILD_DIR=".build"
TEST_BUILD_DIR="test-build"
PYTHON_STANDALONE_VERSION="3.14.5" # macOS standalone CPython (python-build-standalone)
PYTHON_STANDALONE_RELEASE_TAG="20260510"
PIP_VERSION="26.1.2"
POETRY_VERSION="2.4.1"
SETUPTOOLS_VERSION="82.0.1"
POETRY_PLUGIN_EXPORT_VERSION="1.10.0"
PROJECT_NAME="csv2notion_neo"To modify the script behavior, edit the configuration section at the top of local-test-build.sh.
# Show script help
./scripts/local-test-build.sh --help
# Check script configuration
head -30 scripts/local-test-build.shIf you encounter issues with the build script:
- Run
./scripts/local-test-build.sh --clean - Try a fresh build
- Check the prerequisites
- Review the troubleshooting section above
- The script only downloads and installs packages from trusted sources (PyPI, python-build-standalone, Poetry)
- All dependencies are installed in isolated environments under
.build/ - No system-wide installations or modifications are made
- The build environment is completely ephemeral and can be safely deleted
- Version pinning ensures reproducible builds across environments
This build script pins the local macOS toolchain as follows:
- Python: standalone 3.14.5 locally; CI should use 3.14 via
actions/setup-python - pip: 26.1.2 (local bootstrap)
- Poetry: 2.4.1
- Setuptools: 82.0.1
- poetry-plugin-export: 1.10.0
- PyInstaller: latest (installed in the Poetry venv during build)
Update .github/workflows/build.yml and related workflows so env blocks use the same Poetry, setuptools, and export-plugin versions when you roll out Python 3.14 in CI.
Note: This script is designed to be completely self-contained and safe to run. It will not modify your system Python installation or install any packages globally.
The docker-run.sh script provides a convenient way to set up and run CSV2Notion Neo in a Docker container environment.
# From the project root directory
./scripts/docker-run.shThis will:
- Build the Docker image using Docker Buildx
- Create and start a container with the project mounted
- Set up SSH access on port 2222
- Base Image: Python 3.11-slim
- Package Manager: Poetry
- Memory Limit: 512MB
- CPU Limit: 1.0 cores
- Port: 2222 (SSH)
- Volume Mount: Current directory mounted to
/app
The container runs in detached mode with SSH access on port 2222:
ssh -p 2222 root@localhostYou can also run the Docker setup directly:
# From the docker directory
cd docker
./install_from_docker.sh- Docker and Docker Buildx installed
- SSH client (for container access)
For more detailed information, see the Docker README.