name: 'Solarboat CLI Action'
description: 'Run Solarboat CLI commands in your GitHub Actions workflow'
branding:
icon: 'anchor'
color: 'blue'
inputs:
command:
description: 'Command to run (scan, plan, or apply)'
required: true
output-dir:
description: 'Directory to save Terraform plan files'
default: 'terraform-plans'
required: false
apply-dryrun:
description: 'Run apply in dry-run mode (enabled by default for safety)'
default: 'true'
required: false
ignore-workspaces:
description: 'Comma-separated list of workspaces to ignore'
required: false
default: ''
path:
description: 'Directory to scan for modules (default: .)'
required: false
default: '.'
all:
description: 'Process all stateful modules regardless of changes'
required: false
default: 'false'
watch:
description: 'Show real-time output (forces parallel=1)'
required: false
default: 'false'
parallel:
description: 'Number of parallel module processes (max 4)'
required: false
default: '1'
default-branch:
description: 'Default git branch to compare against for changes'
required: false
default: 'main'
var-files:
description: 'Comma-separated list of var files to use'
required: false
default: ''
github_token:
description: 'GitHub token for PR comments'
required: true
runs:
using: 'composite'
steps:
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Install Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.7.4"
- name: Install Solarboat CLI
shell: bash
run: |
# Install Solarboat CLI using cargo
cargo install solarboat
# Verify installation
solarboat --version || (echo "Installation failed" && exit 1)
- name: Run Solarboat CLI
shell: bash
run: |
echo "đ Running Solarboat CLI"
# Build CLI args from inputs
IGNORE_WORKSPACES_ARG=""
if [ ! -z "${{ inputs.ignore-workspaces }}" ]; then
IGNORE_WORKSPACES_ARG="--ignore-workspaces ${{ inputs.ignore-workspaces }}"
fi
VAR_FILES_ARG=""
if [ ! -z "${{ inputs.var-files }}" ]; then
VAR_FILES_ARG="--var-files ${{ inputs.var-files }}"
fi
ALL_ARG=""
if [ "${{ inputs.all }}" == "true" ]; then
ALL_ARG="--all"
fi
WATCH_ARG=""
if [ "${{ inputs.watch }}" == "true" ]; then
WATCH_ARG="--watch"
fi
PARALLEL_ARG=""
if [ ! -z "${{ inputs.parallel }}" ]; then
PARALLEL_ARG="--parallel ${{ inputs.parallel }}"
fi
DEFAULT_BRANCH_ARG=""
if [ ! -z "${{ inputs.default-branch }}" ]; then
DEFAULT_BRANCH_ARG="--default-branch ${{ inputs.default-branch }}"
fi
PATH_ARG=""
if [ ! -z "${{ inputs.path }}" ]; then
PATH_ARG="--path ${{ inputs.path }}"
fi
OUTPUT_DIR_ARG=""
if [ ! -z "${{ inputs.output-dir }}" ]; then
OUTPUT_DIR_ARG="--output-dir ${{ inputs.output-dir }}"
fi
DRY_RUN_ARG=""
if [ ! -z "${{ inputs.apply-dryrun }}" ]; then
DRY_RUN_ARG="--dry-run=${{ inputs.apply-dryrun }}"
fi
if [[ "${{ inputs.command }}" == "scan" ]]; then
solarboat scan $PATH_ARG $ALL_ARG $DEFAULT_BRANCH_ARG
elif [[ "${{ inputs.command }}" == "plan" ]]; then
solarboat plan $PATH_ARG $OUTPUT_DIR_ARG $IGNORE_WORKSPACES_ARG $ALL_ARG $VAR_FILES_ARG $WATCH_ARG $PARALLEL_ARG $DEFAULT_BRANCH_ARG
elif [[ "${{ inputs.command }}" == "apply" ]]; then
solarboat apply $PATH_ARG $DRY_RUN_ARG $IGNORE_WORKSPACES_ARG $ALL_ARG $VAR_FILES_ARG $WATCH_ARG $PARALLEL_ARG $DEFAULT_BRANCH_ARG
else
echo "â Invalid command: ${{ inputs.command }}"
exit 1
fi
- name: Upload Terraform Plans
if: inputs.command == 'plan'
uses: actions/upload-artifact@v4
with:
name: terraform-plans
path: ${{ inputs.output-dir }}/
retention-days: 5
- name: Comment on PR
if: github.event_name == 'pull_request' && inputs.command == 'plan'
uses: actions/github-script@v7
with:
github-token: ${{ inputs.github_token }}
script: |
const artifactUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}/artifacts`;
const comment = `## đ Solarboat CLI Results
Solarboat has analyzed your Terraform changes and generated plans.
### đ Summary
- ⨠Plans have been generated and uploaded as artifacts
- đ Review the plans before merging
- âąī¸ Plans will be retained for 5 days
### đ Links
- [View Plan Artifacts](${artifactUrl})
### âšī¸ Next Steps
1. Download and review the plan artifacts
2. Address any issues found in the plans
3. Merge the PR when ready
> Note: Check the action logs for detailed module processing information.`;
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});