Skip to content

Latest commit

 

History

History
379 lines (268 loc) · 9.91 KB

File metadata and controls

379 lines (268 loc) · 9.91 KB

Development Guide

Guide for contributors and developers working on dotbak.


Development

Fast iteration with dotbak-dev

The dotbak-dev script sources modules directly without building:

# Edit any module
vim src/commands/status.sh

# Test immediately (no build!)
./dotbak-dev status

# When ready for production
./build.sh
./install.sh

Project structure

dotbak/
├── src/
│   ├── core/         # Core utilities (colors, paths, config)
│   ├── utils/        # Utilities (tree, ignore, symlink, common)
│   ├── commands/     # Command implementations (11 commands)
│   │   ├── init.sh, add.sh, remove.sh, list.sh, status.sh
│   │   ├── snapshot.sh     # Snapshot management
│   │   ├── symlink-sync.sh # Symlink detection
│   │   ├── deploy.sh       # Machine deployment
│   │   └── archive.sh, ignored.sh, version.sh, update.sh
│   └── main.sh       # Entry point and routing
├── test/             # bats-core test suite
│   ├── bats/         # bats-core (pinned to v1.14.0)
│   ├── test_helper/  # bats helpers (pinned versions)
│   ├── unit/         # Unit tests
│   └── integration/  # Integration tests
├── tools/shc/        # Vendored shc compiler (GPLv3) for native binary build
├── dotbak-dev        # Development runner (sources src/ live)
├── build.sh          # Compile to native binary via shc (--script for plain mode)
├── install.sh        # Installation script
└── update-test-deps.sh  # Test dependency updater

Test dependency versions

Pinned versions (tested and stable):

  • bats-core: v1.14.0
  • bats-support: v0.3.0
  • bats-assert: v2.2.4

These are pinned in .gitmodules to ensure stability. We don't automatically update to avoid breaking changes.

bats-core v1.14.0 notes (from upstream changelog):

  • run now honors set -e inside functions (intentional behavior change).
  • Empty suites now fail unless --allow-empty-suite is passed.
  • Helpers stay on latest releases; bats-support master has unreleased license work — stay on the tag.

Releasing a New Version

Step-by-step process for maintainers to cut a release.

Prerequisites

  • You have push access to the repository
  • All changes for the release are merged to main
  • CI is green on main

Steps

1. Decide the version number

We use Semantic Versioning: MAJOR.MINOR.PATCH.

  • PATCH (0.1.00.1.1): bug fixes, documentation
  • MINOR (0.1.00.2.0): new features, backward-compatible
  • MAJOR (0.1.01.0.0): breaking changes

2. Update the VERSION file

echo "0.2.0" > VERSION

This is the single source of truthbuild.sh, dotbak-dev, CI, and the release workflow all read from it.

3. Update CHANGELOG.md

Move items from [Unreleased] (if present) into a new version section:

## [0.2.0] - 2026-08-01

### Added
- ...

### Fixed
- ...

4. Build and verify locally

./build.sh
./dotbak --version          # should show the new version
./test.sh                   # all tests must pass

5. Commit the release

git add VERSION CHANGELOG.md
git commit -m "release: v0.2.0"

6. Create an annotated tag

git tag -a v0.2.0 -m "Release v0.2.0"

The tag must match the VERSION file content (the release workflow verifies this and fails on mismatch).

7. Push the commit and tag

git push origin main
git push origin v0.2.0

Pushing the tag triggers the release workflow (.github/workflows/release.yml) which:

  1. Runs the full test suite
  2. Verifies VERSION file matches the git tag
  3. Builds native binaries (dotbak-linux-x86_64, dotbak-darwin-arm64)
  4. Builds a portable script (dotbak-portable)
  5. Generates SHA256SUMS for all artifacts
  6. Extracts release notes from CHANGELOG.md
  7. Creates a GitHub Release with all artifacts attached

8. Verify the release

  • Check the Actions tab — the release workflow should complete green
  • Check the Releases page — the new release should appear with all artifacts
  • Test the update path: dotbak update --check from an older version

Pre-releases

For beta/RC releases, use a hyphenated tag (e.g., v0.2.0-beta.1). The release workflow automatically marks tags containing - as pre-releases on GitHub.

Release artifacts

The release workflow produces these artifacts:

Artifact Description
dotbak-linux-x86_64 Native binary for Linux (x86_64)
dotbak-darwin-arm64 Native binary for macOS (Apple Silicon)
dotbak-portable Plain shell script (works on any platform with Bash 4.0+)
SHA256SUMS Checksums for all artifacts (used by dotbak update for verification)

Troubleshooting releases

Release workflow failed with "VERSION file does not match tag": The VERSION file content must exactly match the tag (without the v prefix). Fix the VERSION file, amend the commit, delete and re-push the tag.

Self-update downloads wrong artifact: dotbak update auto-detects the platform and downloads the matching artifact. It falls back to dotbak-portable for unrecognized platforms.


Troubleshooting

Broken symlink detected?

# Check status
dotbak status

# Remove and re-add
dotbak remove ~/.zshrc
dotbak add ~/.zshrc

Archive failed?

# Check disk space and zip availability
df -h ~/.dotbak
which zip

# Retry
dotbak archive test-run

Update failed?

# Check internet
curl -I https://github.com

# Manual update (pick your platform)
curl -fsSL https://github.com/darshithedpara/dotbak/releases/latest/download/dotbak-linux-x86_64 -o /tmp/dotbak
sudo mv /tmp/dotbak /usr/local/bin/dotbak
sudo chmod +x /usr/local/bin/dotbak

Command not found after install?

If installed to ~/.local/bin, add to your PATH:

echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Uninstall

# Remove tracked files (optional)
dotbak remove ~/.zshrc
dotbak remove ~/.config/nvim
# ... for each tracked file

# Or just remove dotbak
sudo rm /usr/local/bin/dotbak

# Optional: remove backup directory
rm -rf ~/.dotbak

License

MIT License - see LICENSE file for details

Testing

dotbak includes comprehensive test coverage using bats-core.

For safe testing without risking your real dotfiles, see the Sandbox Testing Guide — covers quick local sandboxes, Docker, VMs, and CI.

For Contributors

Setup (first time only):

# Clone with submodules
git clone --recurse-submodules https://github.com/darshithedpara/dotbak

# Or if already cloned
git submodule update --init --recursive

Running tests:

# All tests (148 total)
./test.sh

# Quick tests (unit only, ~5 seconds)
./test.sh unit

# Integration tests only (~30 seconds)
./test.sh integration

# Specific test file
./test.sh test/unit/test_paths.bats

Test coverage:

  • Unit tests (test/unit/): Test individual functions and modules

    • test_colors.bats - Color output functions
    • test_paths.bats - Path manipulation utilities
    • test_config.bats - Configuration management
    • test_ignore.bats - Ignore pattern matching
    • test_symlink.bats - Symlink operations
  • Integration tests (test/integration/): Test full commands end-to-end

    • test_init.bats - Initialization
    • test_add.bats - Adding files
    • test_list.bats - Listing files
    • test_status.bats - Status reporting
    • test_remove.bats - Removing files
    • test_deploy.bats - Deploying files to a new machine
    • test_snapshot.bats - Snapshot management
    • test_archive.bats - Creating archives
    • test_sync.bats - Symlink-sync detection
    • test_ignored.bats - Ignore management

Before submitting PR:

  1. Run ./test.sh - all tests must pass
  2. Add tests for new features
  3. Update tests for bug fixes

Updating Test Dependencies

Important: Test dependencies (bats-core and helpers) are pinned to specific versions to prevent breaking changes.

Current pinned versions:

  • bats-core: v1.14.0
  • bats-support: v0.3.0
  • bats-assert: v2.2.4

Checking for updates:

# Check if updates are available
./update-test-deps.sh

Update process (maintainers only):

# 1. Check release notes for breaking changes
#    https://github.com/bats-core/bats-core/releases
#    https://github.com/bats-core/bats-support/releases
#    https://github.com/bats-core/bats-assert/releases

# 2. Update submodules to new versions
cd test/bats && git checkout v1.14.0 && cd ../..
cd test/test_helper/bats-support && git checkout v0.4.0 && cd ../../..
cd test/test_helper/bats-assert && git checkout v2.3.0 && cd ../../..

# 3. Run full test suite
./test.sh

# 4. If tests pass, update configuration
#    - Edit .gitmodules (update branch values)
#    - Edit update-test-deps.sh (update version variables)

# 5. Commit changes
git add test/ .gitmodules update-test-deps.sh
git commit -m "chore: update test dependencies to vX.X.X"

Why pin versions?

  • ✅ Prevents surprise breaking changes
  • ✅ Reproducible builds
  • ✅ Controlled updates with testing
  • ✅ Stability for users and CI/CD

When to update:

  • Major bats-core releases (test thoroughly!)
  • Security fixes
  • Bug fixes we need
  • When adding new features that require new bats features

Development Workflow

# Edit source files in src/
vim src/commands/add.sh

# Test immediately (no rebuild needed!)
./dotbak-dev add ~/.testfile

# Run tests
./test.sh

# Build native binary (requires gcc)
./build.sh

# Or build plain script (no compiler needed)
./build.sh --script

Contributing

See CONTRIBUTING.md for the full contributor guide — dev setup, coding conventions, commit messages, and PR workflow.