This guide covers development workflows, testing, troubleshooting, and CI/CD for opencoder contributors.
Run validation and container tests locally before pushing:
# Validate configuration and scripts
./scripts/validate.sh
# Build container
./scripts/build.sh --tag opencoder:test
# Run container test suite
./scripts/container-test.sh opencoder:test-
Build without cache:
./scripts/build.sh --tag opencoder-test --no-cache
-
Run validation tests:
podman run -it --rm opencoder-test bash -c " opencode --version && cat /etc/opencode/opencode.jsonc && test -f /etc/opencode/opencode.jsonc && ls -la /vendor/bin && echo 'All checks passed' "
-
Run comprehensive test suite:
./scripts/container-test.sh opencoder-test
-
Scan for vulnerabilities:
podman image scan opencoder-test
# Run all validations
./scripts/validate.sh
# Or manually
jq . build/.opencode/opencode.json
shellcheck build/entrypoint.sh scripts/*.sh-
Make changes
-
Run validation:
./scripts/validate.sh -
Build and test:
./scripts/build.sh --tag test && ./scripts/container-test.sh test -
Commit with conventional commits:
git commit -m "feat: add new plugin" git commit -m "fix: resolve config issue" git commit -m "chore: update dependencies"
This project includes automated CI/CD via GitHub Actions:
- Validate - Lints shell scripts, validates JSON configuration
- Build - Builds the container image with Podman/Docker
- Test - Runs the container test suite
- Push - Pushes image to GitHub Container Registry (main branch only)
# Run the same validations as CI
./scripts/validate.sh
# Build and test like CI does
./scripts/build.sh --tag opencoder:ci
./scripts/container-test.sh opencoder:ci podmanPull the latest container from GitHub Container Registry:
podman pull ghcr.io/tankdonut/opencoder:latest
podman run -it --rm ghcr.io/tankdonut/opencoder:latest- Workflows:
.github/workflows/(4 files —lint-and-test.yaml,build-and-publish-image.yaml,prune-ghcr-images.yaml,renovate-auto-approve.yaml); consume centralized actions fromtankdonut/github-actions@v1 - Test script:
scripts/container-test.sh - Validation:
scripts/validate.sh
Symptom: COPY --from=tools fails
Solution: Verify base image is accessible:
podman pull ghcr.io/tankdonut/toolsSymptom: Container can't find opencode.json
Solution: Ensure config exists at the correct path:
ls -la build/.opencode/opencode.jsonSymptom: Can't write to /app or /workspace
Solution: Container runs as non-root user opencode (UID 1000). Match host permissions:
chown -R 1000:1000 /path/to/workspaceSymptom: Invalid JSON syntax error
Solution: Validate with jq:
jq . build/.opencode/opencode.json./scripts/local-setup.sh [OPTIONS]
OPTIONS:
--skip-install Skip OpenCode installation
--skip-config Skip OpenCode config setup
--version VERSION Install specific OpenCode version
-h, --help Show help message
EXAMPLES:
./scripts/local-setup.sh # Full setup
./scripts/local-setup.sh --skip-install # Setup without installing OpenCode
./scripts/local-setup.sh --version 2.0.0 # Install specific version-
Add the plugin to
opencode.jsonwith a pinned version:{ "plugin": [ "existing-plugin", "new-plugin" ] } -
Test in container:
./scripts/build.sh --tag opencoder --no-cache
Add a new skill source using the skills.sh CLI:
npx skills@1.5.13 add <owner/repo> --agent opencode --skill '*' --copy -yThen commit the updated build/skills-lock.json.
Regenerate the lockfile and rebuild:
npx skills@1.5.13 experimental_install
git add build/skills-lock.json
git commit -m "chore: refresh skills lockfile"The OpenCode version is managed in build/.opencode-version (single source of truth). The build script reads the version from this file automatically:
./scripts/build.shTo use Docker instead of Podman:
./scripts/build.sh --runtime dockerTo change the OpenCode version, use the version bumper script:
./scripts/bump-version.sh 1.14.18
./scripts/build.sh- No secrets in containers: API keys and credentials never committed or baked into images
- Non-root user: Containers run as
opencodeuser (UID 1000) - Pinned versions: All base images and packages use explicit versions
- Minimal images: Only essential dependencies installed
- Vulnerability scanning: Run
podman image scanbefore releases