An open API service indexing awesome lists of open source software.

https://github.com/sultann/branch-deploy-action

Deploy filtered content to any branch with git history preservation. Supports .distignore, manual exclusions, and build scripts.
https://github.com/sultann/branch-deploy-action

automation branch-deployment ci-cd deployment distignore git-history github-actions wordpress

Last synced: 5 days ago
JSON representation

Deploy filtered content to any branch with git history preservation. Supports .distignore, manual exclusions, and build scripts.

Awesome Lists containing this project

README

          

# Branch Deploy Action

Deploy filtered content from one branch to another while preserving git history. Designed for creating distribution branches with build artifacts but without development files.

## Features

- Deploy from any branch to any branch with history preservation
- Support for `.distignore`, `.deployignore`, or custom ignore files
- Manual exclusions and inclusions (override patterns)
- Optional build scripts (composer, npm, custom commands)
- Automatic composer.json cleanup for distribution
- Customizable commit messages with placeholders
- Secure token management

## Quick Start

```yaml
name: Deploy to Trunk

on:
push:
branches: [master]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: sultann/branch-deploy-action@v1
with:
target-branch: trunk
```

## Common Use Cases

### WordPress Plugin Distribution

Deploy to trunk without development files:

```yaml
- uses: sultann/branch-deploy-action@v1
with:
target-branch: trunk
ignore-file: .distignore
script-before: composer install --no-dev --optimize-autoloader
```

The action automatically cleans `composer.json` by removing `.extra`, `.scripts`, `.config`, `.repositories`, `require-dev`, and `autoload-dev`.

Disable composer cleanup if needed:

```yaml
composer-cleanup: false
```

### Keep Workflows in Trunk

Sometimes you want trunk to have `.github` for workflows, but your `.distignore` excludes it. Use `include-paths` to override:

```yaml
- uses: sultann/branch-deploy-action@v1
with:
target-branch: trunk
ignore-file: .distignore # excludes .github
include-paths: .github # but include it anyway
```

### NPM Package Distribution

```yaml
- uses: sultann/branch-deploy-action@v1
with:
target-branch: dist
ignore-file: .npmignore
script-before: |
npm ci
npm run build
```

## Configuration

### Inputs

| Input | Description | Required | Default |
|-------|-------------|----------|---------|
| `source-branch` | Branch to deploy from | No | Current branch |
| `target-branch` | Branch to deploy to | Yes | - |
| `ignore-file` | Path to ignore file | No | `.distignore` |
| `include-paths` | Paths to include (overrides ignore-file) | No | - |
| `script-before` | Commands to run before deployment | No | - |
| `composer-cleanup` | Clean composer.json for distribution | No | `true` |
| `commit-message` | Commit message template | No | `Deploy from {source-branch} ({commit-short-sha})` |
| `github-token` | GitHub authentication token | No | Auto-detected |

### Commit Message Templates

Customize commit messages with placeholders:

- `{source-branch}` - Name of the source branch
- `{commit-sha}` - Full commit hash
- `{commit-short-sha}` - Abbreviated commit hash

Example:
```yaml
commit-message: "Release from {source-branch} - {commit-short-sha}"
```

### Ignore File Format

Standard gitignore-style format with negation support:

```
# .distignore example
.git
.github
node_modules
tests
*.md
!README.md
```

### How Exclusions Work

The action processes patterns in this order:

1. Default exclusions (`.git/`, `node_modules/`, `deploy-temp/`)
2. **Includes from `include-paths`** (processed FIRST so they override ignore-file)
3. Patterns from `ignore-file`

**Key point:** `include-paths` is processed before `ignore-file`, so you can override exclusions.

## How It Works

1. Validates inputs and runs build script (if provided)
2. Cleans composer.json (if enabled)
3. Builds exclusion list from ignore file + manual paths
4. Copies filtered files to temporary directory using rsync
5. Initializes git and syncs with remote target branch
6. Uses `git reset --soft` to preserve history
7. Commits changes and pushes to target branch

The action cleans up temporary files on exit, even on failure.

## Troubleshooting

**No changes detected**

Check your ignore file - it might exclude everything. Common issue: `.distignore` has `.*` which excludes all dotfiles.

**Permission errors**

Ensure your GitHub token has `contents: write` permission.

**Push rejected**

The target branch may have protection rules. Check branch settings or use a different workflow trigger.

## Security

The action uses git credential helper with cleanup on exit. Tokens never appear in logs or command output. All inputs are validated before execution.

## Testing Locally

Test the deployment script locally:

```bash
export GITHUB_REPOSITORY="owner/repo"
export GITHUB_TOKEN="your-token"
export TARGET_BRANCH="test-branch"
export IGNORE_FILE=".distignore"

bash deploy.sh
```

## Publishing

To publish this action:

1. Create repository at `github.com/sultann/branch-deploy-action`
2. Copy files to repository root
3. Tag a release: `git tag -a v1.0.0 -m "Initial release"`
4. Push tags: `git push --tags`
5. Create major version tag: `git tag -a v1 -m "Version 1" && git push origin v1`

Users can then reference it:
```yaml
- uses: sultann/branch-deploy-action@v1
```

## License

MIT License

## Author

Sultan Nasir Uddin ([sultann](https://github.com/sultann))