Complete reference documentation for all inputs, outputs, and behavior of the SST Operations Action.
name: 'SST Operations Action'
description: 'A unified GitHub Action for SST operations: deploy, diff, remove, and stage'
author: 'Kodehort'
branding:
icon: 'cloud'
color: 'orange'
runs:
using: 'node24'
main: 'dist/index.js'Runtime Requirements:
- Node.js 24 or higher (handled automatically by GitHub Actions)
- GitHub Actions environment
- Repository with SST configuration
All inputs are defined in action.yml and processed by the action's validation system.
Description: SST operation to perform
Required: No
Default: "deploy"
Type: String (Enum)
Valid Values:
"deploy"- Deploy SST application to specified stage"diff"- Show infrastructure changes without deploying"remove"- Remove all resources for specified stage"stage"- Calculate stage name from Git branch or pull request
Examples:
# Default operation (deploy)
- uses: kodehort/sst-operations-action@v1
with:
stage: staging
token: ${{ secrets.GITHUB_TOKEN }}
# Explicit operation
- uses: kodehort/sst-operations-action@v1
with:
operation: diff
stage: staging
token: ${{ secrets.GITHUB_TOKEN }}
# Stage calculation operation
- uses: kodehort/sst-operations-action@v1
with:
operation: stage
token: ${{ secrets.GITHUB_TOKEN }}Validation:
- Must be one of the valid values
- Case-sensitive string matching
- Defaults to
"deploy"if not specified
Description: SST stage to operate on (automatically computed from Git context if not provided)
Required: No
Default: Auto-computed from Git context (branch/PR name)
Type: String
Valid Format:
- Alphanumeric characters and hyphens only
- Must start with letter or number
- Maximum length: 128 characters
- Minimum length: 1 character
Examples:
# Automatic stage inference (recommended)
# Stage computed from Git context (branch/PR name)
- uses: kodehort/sst-operations-action@v1
with:
operation: deploy
# No stage input - automatically computed
token: ${{ secrets.GITHUB_TOKEN }}
# Explicit stage names
stage: production
stage: staging
stage: development
# Dynamic stage names
stage: pr-${{ github.event.number }}
stage: feature-${{ github.run_id }}
stage: ${{ github.ref_name }}
# Sanitized branch names
stage: ${{ steps.sanitize.outputs.stage }}Common Patterns:
production- Production environmentstaging- Staging environmentpr-123- Pull request environmentsdev-john- Developer-specific stagesfeature-xyz- Feature branch stages
Validation:
- Optional input for all operations (automatically computed from Git context if not provided)
- When provided, must match regex:
^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$ - Cannot be empty string if explicitly provided
- Falls back to automatic computation from branch/PR name when omitted
Description: GitHub token for authentication and API access
Required: Yes
Default: None
Type: String (Secret)
Usage:
# Built-in token (recommended)
token: ${{ secrets.GITHUB_TOKEN }}
# Personal access token
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}Required Permissions:
permissions:
contents: read # Read repository contents
issues: write # Create/update issue comments
pull-requests: write # Create/update PR commentsToken Capabilities:
- Create and update PR/issue comments
- Set workflow status
- Access repository metadata
Validation:
- Required input, action fails if not provided
- Must be valid GitHub token format
- Token permissions validated at runtime
Description: Controls when PR/issue comments are created
Required: No
Default: "on-success"
Type: String (Enum)
Valid Values:
"always"- Always create comments, regardless of outcome"on-success"- Create comments only when operation succeeds"on-failure"- Create comments only when operation fails"never"- Never create comments
Examples:
# Show diff results in all PRs (auto-computed stage)
- uses: kodehort/sst-operations-action@v1
with:
operation: diff
# Stage automatically computed from PR branch name
token: ${{ secrets.GITHUB_TOKEN }}
comment-mode: always
# Only comment on successful deployments
- uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: production
token: ${{ secrets.GITHUB_TOKEN }}
comment-mode: on-success
# Silent operation (no comments)
- uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: staging
token: ${{ secrets.GITHUB_TOKEN }}
comment-mode: neverComment Context:
- Comments only created in PR and issue contexts
- No comments in push/schedule contexts regardless of mode
- Comments include operation results, URLs, and error details
Validation:
- Must be one of the valid values
- Defaults to
"on-success"if not specified - Case-sensitive string matching
Description: Whether to fail the GitHub Actions workflow when operation fails
Required: No
Default: true
Type: Boolean
Valid Values:
true- Fail workflow when operation fails (recommended)false- Continue workflow even if operation fails
Examples:
# Fail workflow on error (default)
- uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: production
token: ${{ secrets.GITHUB_TOKEN }}
fail-on-error: true
# Continue workflow on error
- uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: staging
token: ${{ secrets.GITHUB_TOKEN }}
fail-on-error: falseUse Cases for false:
- Optional deployments that shouldn't block other jobs
- Exploratory operations where failure is acceptable
- Custom error handling workflows
Behavior:
- When
true: Sets workflow status to failed on operation failure - When
false: Workflow continues, check outputs for success status - Error details always available in outputs regardless of setting
Validation:
- Must be boolean value (
trueorfalse) - String values
"true"and"false"automatically converted - Invalid values default to
true
Description: Maximum size of captured output in bytes
Required: No
Default: 50000 (50KB)
Type: Integer
Valid Range:
- Minimum:
1000(1KB) - Maximum:
1000000(1MB) - Default:
50000(50KB)
Examples:
# Default size (50KB)
- uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: staging
token: ${{ secrets.GITHUB_TOKEN }}
# Increased size for large deployments
- uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: production
token: ${{ secrets.GITHUB_TOKEN }}
max-output-size: 200000 # 200KB
# Debug mode with maximum size
- uses: kodehort/sst-operations-action@v1
with:
operation: diff
stage: staging
token: ${{ secrets.GITHUB_TOKEN }}
max-output-size: 1000000 # 1MBImpact:
- Larger values capture more detailed output
- Smaller values improve performance and reduce memory usage
- Truncated output indicated in
truncatedoutput field
When to Adjust:
- Increase for large SST applications with many resources
- Increase when debugging requires full output
- Decrease for performance-critical workflows
- Decrease when output parsing issues occur
Validation:
- Must be integer between 1000 and 1000000
- Values outside range are clamped to limits
- String values automatically converted to integers
Description: Maximum length for computed stage names (stage operation only)
Required: No
Default: 26
Type: Integer
Valid Range:
- Minimum:
1 - Maximum:
100 - Default:
26
Examples:
# Default length (26 characters)
- uses: kodehort/sst-operations-action@v1
with:
operation: stage
token: ${{ secrets.GITHUB_TOKEN }}
# Custom length for shorter stage names
- uses: kodehort/sst-operations-action@v1
with:
operation: stage
token: ${{ secrets.GITHUB_TOKEN }}
truncation-length: 15
# Longer stage names for environments without naming constraints
- uses: kodehort/sst-operations-action@v1
with:
operation: stage
token: ${{ secrets.GITHUB_TOKEN }}
truncation-length: 50Impact:
- Controls maximum length of computed stage names
- Truncation includes any prefix
- Trailing hyphens are cleaned up after truncation
- Useful for services with specific naming constraints (Route53, ELBs, etc.)
When to Adjust:
- Decrease for strict naming requirements (e.g., Route53 subdomain limits)
- Increase when longer, more descriptive stage names are needed
- Customize based on target infrastructure constraints
Validation:
- Must be integer between 1 and 100
- Values outside range are constrained to limits
- String values automatically converted to integers
Description: Prefix to add when stage name starts with a number (stage operation only)
Required: No
Default: "pr-"
Type: String
Valid Format:
- Maximum length: 10 characters
- Must contain only lowercase letters, numbers, and hyphens
- Can be empty string to disable prefixing
Examples:
# Default prefix ('pr-')
- uses: kodehort/sst-operations-action@v1
with:
operation: stage
token: ${{ secrets.GITHUB_TOKEN }}
# Custom prefix for issue tracking
- uses: kodehort/sst-operations-action@v1
with:
operation: stage
token: ${{ secrets.GITHUB_TOKEN }}
prefix: "issue-"
# No prefix (empty string)
- uses: kodehort/sst-operations-action@v1
with:
operation: stage
token: ${{ secrets.GITHUB_TOKEN }}
prefix: ""
# Ticket system integration
- uses: kodehort/sst-operations-action@v1
with:
operation: stage
token: ${{ secrets.GITHUB_TOKEN }}
prefix: "ticket-"Usage Examples:
| Branch Name | Prefix | Result |
|---|---|---|
123-hotfix |
pr- |
pr-123-hotfix |
456-feature |
fix- |
fix-456-feature |
789-update |
`` (empty) | 789-update |
bug-123 |
issue- |
bug-123 (no prefix, doesn't start with digit) |
Impact:
- Only applied when stage name starts with a digit
- Prefix is included in truncation length calculation
- Useful for integrating with ticket systems or issue trackers
- Ensures valid resource names in cloud environments
When to Customize:
- Issue Tracking: Use
issue-for GitHub issues or Jira tickets - Bug Fixes: Use
fix-orhotfix-for hotfix branches - No Prefix: Use empty string when numeric names are acceptable
- Team Conventions: Match your team's branch naming standards
Validation:
- Maximum 10 characters
- Must match regex:
^[a-z0-9-]*$ - Empty string is valid (disables prefixing)
- Invalid characters are rejected
All outputs are provided as strings (GitHub Actions requirement) and available for use in subsequent workflow steps.
Description: Whether the operation completed successfully
Type: String
Format: "true" or "false"
Usage:
- name: Deploy
id: deploy
uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: staging
token: ${{ secrets.GITHUB_TOKEN }}
- name: Handle Success
if: steps.deploy.outputs.success == 'true'
run: echo "Deployment successful!"
- name: Handle Failure
if: steps.deploy.outputs.success == 'false'
run: echo "Deployment failed!"Values:
"true"- Operation completed successfully"false"- Operation failed or encountered errors
Notes:
- Always set, regardless of operation type
- String comparison required (
== 'true', not== true) - Reflects final operation status after all processing
Description: The operation that was performed
Type: String
Format: Operation name
Values:
"deploy"- Deploy operation was executed"diff"- Diff operation was executed"remove"- Remove operation was executed"stage"- Stage operation was executed
Usage:
- name: Check Operation Type
run: |
case "${{ steps.sst.outputs.operation }}" in
"deploy")
echo "Deployment completed"
;;
"diff")
echo "Diff analysis completed"
;;
"remove")
echo "Resource removal completed"
;;
"stage")
echo "Stage calculation completed"
;;
esacNotes:
- Matches the input
operationparameter - Useful for generic workflows handling multiple operations
- Always set to the actual operation performed
Description: The stage that was operated on
Type: String
Format: Stage name
Usage:
- name: Report Stage
run: |
echo "Operated on stage: ${{ steps.sst.outputs.stage }}"
echo "DEPLOYED_STAGE=${{ steps.sst.outputs.stage }}" >> $GITHUB_ENVNotes:
- Matches the input
stageparameter - Useful for downstream processing and notifications
- Always reflects the actual stage used
Description: The SST application name
Type: String
Format: Application name as SST reports it
Usage:
- name: Use App Name
run: |
APP_NAME="${{ steps.sst.outputs.app }}"
echo "Deployed app: $APP_NAME"
# Use in notifications
curl -X POST $SLACK_WEBHOOK \
-d "{'text': 'Deployed $APP_NAME to ${{ steps.sst.outputs.stage }}'}"Notes:
- Read from the
App:line of the SST CLI's banner output. Nothing readssst.config.ts— the value is whatever SST printed for this run - Empty string if the app name cannot be determined. It is the single fallback:
every operation reports
""rather than inventing a name, so!= ''is a meaningful check in an Actions expression - Always empty for the
stageoperation, which never runs SST - Useful for multi-app repositories
Description: Number of resource changes made
Type: String (Integer)
Format: Numeric string
Values:
"0"- No resources changed"5"- Five resources changed""- Could not determine (parsing failed)
Usage:
- name: Report Resource Changes
run: |
CHANGES="${{ steps.sst.outputs.resource_changes }}"
if [ "$CHANGES" = "0" ]; then
echo "No infrastructure changes"
else
echo "Changed $CHANGES resources"
fiOperation-Specific Behavior:
- Deploy: Number of created, updated, or modified resources
- Diff: Number of planned changes
- Remove: Number of deleted resources
Description: Generic outputs declared by the SST application
Type: String (JSON Array)
Format: JSON-encoded array of { "key": ..., "value": ... } objects
Example Values:
[{"key":"Api","value":"https://api.example.com"}]
[{"key":"Web","value":"https://web.example.com"},{"key":"Api","value":"https://api.example.com"}]
[]Usage:
- name: Deploy
id: deploy
uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: production
token: ${{ secrets.GITHUB_TOKEN }}
- name: Use deployment outputs
run: |
OUTPUTS='${{ steps.deploy.outputs.outputs }}'
# Look one up by name
API_URL=$(echo "$OUTPUTS" | jq -r '.[] | select(.key == "Api") | .value')
echo "API_URL=$API_URL" >> $GITHUB_ENV
# Or iterate every URL-shaped value
for url in $(echo "$OUTPUTS" | jq -r '.[].value | select(startswith("http"))'); do
curl -f "$url/health" || echo "Health check failed for $url"
doneNotes:
- Only populated for
deployoperations; empty string fordiff,removeandstage - Empty array
[]if the deployment declared no outputs - Whatever the SST app declares, not only URLs — parse by
keyrather than assuming position
Description: The resources SST reported during the deployment
Type: String (JSON Array)
Format: JSON-encoded array of { "name": ..., "type": ..., "status": ... } objects
Example Values:
[{"name":"MyFunction","type":"Function","status":"created"}]
[]Usage:
- name: Report created resources
run: |
echo '${{ steps.deploy.outputs.resources }}' \
| jq -r '.[] | select(.status == "created") | "\(.type) \(.name)"'Notes:
- Only populated for
deployoperations; empty string fordiff,removeandstage resource_changesis the count of this array's entriesstatusis normalised by the parser (e.g.created,updated,deleted,failed)
Description: Human-readable summary of planned changes
Type: String
Format: Plain text summary
Example Values:
"3 resources to create, 1 to update"
"No changes detected"
"2 resources to delete"
"5 resources to create, 2 to update, 1 to delete"
Usage:
- name: Show Diff Summary
run: |
SUMMARY="${{ steps.diff.outputs.diff_summary }}"
echo "Infrastructure changes: $SUMMARY"
# Use in PR comments or notifications
if [ -n "$SUMMARY" ]; then
echo "## Infrastructure Changes" >> $GITHUB_STEP_SUMMARY
echo "$SUMMARY" >> $GITHUB_STEP_SUMMARY
fiNotes:
- Only populated for
diffoperations - Empty string if no changes or parsing failed
- Human-readable format for notifications and reports
Description: Number of changes SST plans to make Type: String (Integer) Format: Numeric string
Example Values:
"0"
"27"
Usage:
- name: Gate on planned changes
run: |
if [ "${{ steps.diff.outputs.planned_changes }}" != "0" ]; then
echo "Infrastructure changes are pending review"
fiNotes:
- Only populated for
diffoperations; empty string fordeploy,removeandstage resource_changescarries the same value fordiff, so either can be read
Description: Number of resources removed Type: String (Integer) Format: Numeric string
Usage:
- name: Report cleanup
run: echo "Removed ${{ steps.cleanup.outputs.resources_removed }} resources"Notes:
- Only populated for
removeoperations; empty string fordeploy,diffandstage resource_changescarries the same value forremove
Description: The resources SST removed
Type: String (JSON Array)
Format: JSON-encoded array of { "name": ..., "type": ..., "status": ... } objects
Example Values:
[{"name":"MyFunction","type":"Function","status":"removed"}]
[]Usage:
- name: List removed resources
run: |
echo '${{ steps.cleanup.outputs.removed_resources }}' \
| jq -r '.[] | "\(.type) \(.name)"'Notes:
- Only populated for
removeoperations; empty string fordeploy,diffandstage - Note the name:
resources_removedis the count,removed_resourcesis the list
Description: Computed stage name from Git branch or pull request
Type: String
Format: Stage name (kebab-case)
Example Values:
"main"
"feature-branch"
"user-authentication"
"pr-123-hotfix"
Usage:
- name: Calculate Stage
id: stage-calc
uses: kodehort/sst-operations-action@v1
with:
operation: stage
token: ${{ secrets.GITHUB_TOKEN }}
- name: Use Computed Stage
run: |
STAGE="${{ steps.stage-calc.outputs.computed_stage }}"
echo "Computed stage: $STAGE"
# Use in subsequent operations
echo "DEPLOYMENT_STAGE=$STAGE" >> $GITHUB_ENV
- name: Deploy with Computed Stage
uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: ${{ steps.stage-calc.outputs.computed_stage }}
token: ${{ secrets.GITHUB_TOKEN }}Stage Computation Rules:
- Branch
main→ stagemain - Branch
feature/user-auth→ stageuser-auth - Branch
123-hotfix→ stagepr-123-hotfix - Pull request from
feature/api→ stageapi - Maximum 26 characters for Route53 compatibility
- Sanitized to alphanumeric + hyphens only
Notes:
- Only populated for
stageoperations - Always produces a valid stage name or uses fallback
- Follows consistent naming conventions across environments
Description: Git reference that was used for stage computation
Type: String
Format: Git reference path
Example Values:
"refs/heads/main"
"refs/heads/feature/user-auth"
"feature-branch"
""
Usage:
- name: Show Git Reference
run: |
REF="${{ steps.stage-calc.outputs.ref }}"
echo "Computed from ref: $REF"
# Use in commit status or notifications
if [ -n "$REF" ]; then
echo "Source: $REF" >> $GITHUB_STEP_SUMMARY
fiNotes:
- Only populated for
stageoperations - May be empty if ref cannot be determined
- Useful for debugging stage computation
Description: GitHub event type that triggered the workflow
Type: String
Format: GitHub event name
Example Values:
"push"
"pull_request"
"workflow_dispatch"
"schedule"
Usage:
- name: Handle Event Type
run: |
EVENT="${{ steps.stage-calc.outputs.event_name }}"
case "$EVENT" in
"pull_request")
echo "Processing pull request stage"
;;
"push")
echo "Processing push event stage"
;;
*)
echo "Processing $EVENT event stage"
;;
esacNotes:
- Only populated for
stageoperations - Matches
github.context.eventName - Useful for conditional logic based on event type
Description: Whether the stage was computed from a pull request
Type: String
Format: "true" or "false"
Values:
"true"- Stage computed from pull request context"false"- Stage computed from push or other event
Usage:
- name: Handle Pull Request
run: |
if [ "${{ steps.stage-calc.outputs.is_pull_request }}" = "true" ]; then
echo "This is a pull request deployment"
echo "Stage: ${{ steps.stage-calc.outputs.computed_stage }}"
echo "Will be cleaned up when PR closes"
else
echo "This is a direct branch deployment"
fiNotes:
- Only populated for
stageoperations - String comparison required (
== 'true', not== true) - Useful for conditional cleanup workflows
Description: Final operation status with additional detail
Type: String
Format: Status keyword
Values:
"success"- Operation completed successfully"failed"- Operation failed completely"partial"- Operation partially completed (some resources succeeded)"timeout"- Operation timed out"cancelled"- Operation was cancelled
Usage:
- name: Handle Completion Status
run: |
STATUS="${{ steps.sst.outputs.completion_status }}"
case "$STATUS" in
"success")
echo "✅ Full success"
;;
"partial")
echo "⚠️ Partial completion - review required"
;;
"failed"|"timeout"|"cancelled")
echo "❌ Operation failed: $STATUS"
exit 1
;;
esacRelationship to success:
success: "true"whencompletion_status: "success"success: "false"for all other completion statuses- Provides more granular information than boolean success
Description: SST Console permalink for operation results
Type: String
Format: URL or empty string
Example Values:
"https://console.sst.dev/apps/my-app/stages/production/deployments/123"
""
Usage:
- name: Share Console Link
run: |
PERMALINK="${{ steps.sst.outputs.permalink }}"
if [ -n "$PERMALINK" ]; then
echo "📊 View details: $PERMALINK"
echo "SST_CONSOLE_URL=$PERMALINK" >> $GITHUB_ENV
else
echo "No console permalink available"
fiNotes:
- May be empty if SST Console integration unavailable
- Useful for sharing operation details with team
- Links to relevant SST Console sections
Description: Whether operation output was truncated due to size limits
Type: String
Format: "true" or "false"
Values:
"true"- Output was truncated, some information may be missing"false"- Complete output captured
Usage:
- name: Check for Truncated Output
run: |
if [ "${{ steps.sst.outputs.truncated }}" = "true" ]; then
echo "⚠️ Output was truncated"
echo "Consider increasing max-output-size parameter"
echo "Some details may be missing from parsing"
fiWhen Output is Truncated:
- Output exceeded
max-output-sizeparameter - Parsing may be incomplete or less accurate
- Consider increasing
max-output-sizefor full output
Description: Error message when the operation fails Type: String Format: Plain text; empty on success
Usage:
- name: Report failure
if: failure()
run: |
echo "SST ${{ steps.sst.outputs.operation }} failed:"
echo "${{ steps.sst.outputs.error }}"Notes:
- Populated for every operation, including
stage - Empty string when the operation succeeded, so test for emptiness rather than presence
- Set independently of
fail-on-error: withfail-on-error: falsethe workflow continues and this output is the way to detect the failure
Detailed behavior for each operation type.
Purpose: Deploy SST application to specified stage
Process:
- Execute
sst deploy --stage {stage} - Parse deployment output for resources and generic outputs
- Extract URLs and other outputs from generic parsing
- Create PR comments with deployment results
Typical Duration: 30 seconds to 15 minutes (default timeout)
Success Conditions:
- SST deploy command exits with code 0
- No critical CloudFormation errors
- Resources successfully created/updated
Outputs Populated:
- All standard outputs
outputs- JSON array of the app's declared outputs, as{key, value}pairsresources- JSON array of the resources SST reportedresource_changes- Number of resources modified
Example:
- name: Deploy to Production
id: deploy
uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: production
token: ${{ secrets.GITHUB_TOKEN }}
comment-mode: on-success
- name: Test Deployed Application
run: |
URLS=$(echo '${{ steps.deploy.outputs.outputs }}' | jq -r '.[].value | select(type == "string" and startswith("http"))')
for url in $URLS; do
curl -f "$url/health" || exit 1
donePurpose: Show planned infrastructure changes without deploying
Process:
- Execute
sst diff --stage {stage} - Parse diff output for planned changes
- Generate human-readable change summary
- Create PR comments with change preview
- No actual infrastructure modifications
Typical Duration: 10-60 seconds
Success Conditions:
- SST diff command exits successfully
- Changes successfully analyzed (even if no changes)
Outputs Populated:
- All standard outputs (no URLs for diff operations)
diff_summary- Human-readable change summaryresource_changes- Number of planned changes
Example:
- name: Show Infrastructure Changes
id: diff
uses: kodehort/sst-operations-action@v1
with:
operation: diff
stage: staging
token: ${{ secrets.GITHUB_TOKEN }}
comment-mode: always
- name: Evaluate Changes
run: |
CHANGES="${{ steps.diff.outputs.resource_changes }}"
if [ "$CHANGES" -gt "10" ]; then
echo "Large number of changes detected: $CHANGES"
echo "Manual review recommended"
fiPurpose: Remove all resources for specified stage
Process:
- Execute
sst remove --stage {stage} - Parse removal output for deleted resources
- Track cleanup status and any remaining resources
- Create PR comments with cleanup results
- Handle partial cleanup scenarios
Typical Duration: 1-10 minutes
Success Conditions:
- SST remove command completes
- Resources successfully deleted (partial success acceptable)
Outputs Populated:
- All standard outputs (no URLs or diff summaries for remove operations)
resource_changes- Number of resources removedcompletion_status- May be "partial" for incomplete removal
Example:
- name: Cleanup PR Environment
id: cleanup
uses: kodehort/sst-operations-action@v1
with:
operation: remove
stage: pr-${{ github.event.number }}
token: ${{ secrets.GITHUB_TOKEN }}
fail-on-error: false # Allow partial cleanup
- name: Handle Cleanup Results
run: |
if [ "${{ steps.cleanup.outputs.success }}" = "false" ]; then
echo "Cleanup issues detected"
echo "Status: ${{ steps.cleanup.outputs.completion_status }}"
# Manual cleanup may be required
fiPurpose: Calculate stage name from Git branch or pull request information
Process:
- Extract Git reference from GitHub context
- Apply stage computation rules and sanitization
- Generate Route53-compatible stage name (≤26 characters)
- Provide detailed context about computation
- No SST CLI execution required
Typical Duration: < 1 second
Success Conditions:
- Git reference successfully extracted or fallback stage available
- Stage name passes validation rules
- GitHub context accessible
Outputs Populated:
- All standard outputs
computed_stage- Final computed stage nameref- Git reference used for computationevent_name- GitHub event typeis_pull_request- Whether from pull request context
Stage Computation Algorithm:
- Extract Reference: Get Git ref from GitHub context based on event type
- Remove Prefixes: Strip
refs/heads/,feature/, etc. - Normalize: Convert to lowercase
- Sanitize: Replace non-alphanumeric chars with hyphens
- Clean: Remove leading/trailing hyphens
- Truncate: Limit to 26 characters for Route53
- Fix Numeric: Prefix with
pr-if starts with digit
Example:
- name: Calculate Stage Name
id: stage-calc
uses: kodehort/sst-operations-action@v1
with:
operation: stage
token: ${{ secrets.GITHUB_TOKEN }}
stage: fallback-stage # Optional fallback
truncation-length: 20 # Custom length
prefix: issue- # Custom prefix
- name: Use Computed Stage
run: |
STAGE="${{ steps.stage-calc.outputs.computed_stage }}"
REF="${{ steps.stage-calc.outputs.ref }}"
IS_PR="${{ steps.stage-calc.outputs.is_pull_request }}"
echo "Computed stage: $STAGE (from $REF)"
if [ "$IS_PR" = "true" ]; then
echo "This is a pull request preview environment"
fi
- name: Deploy to Computed Stage
uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: ${{ steps.stage-calc.outputs.computed_stage }}
token: ${{ secrets.GITHUB_TOKEN }}Stage Computation Examples:
| Input Branch/Ref | Event Type | Config | Computed Stage | Notes |
|---|---|---|---|---|
main |
push | Default | main |
Direct mapping |
feature/user-auth |
push | Default | user-auth |
Prefix removed |
feature/user-auth |
pull_request | Default | user-auth |
Same result for PR |
123-hotfix |
push | Default | pr-123-hotfix |
Numeric prefix added |
123-hotfix |
push | prefix: "fix-" |
fix-123-hotfix |
Custom prefix |
123-hotfix |
push | prefix: "" |
123-hotfix |
No prefix |
Feature_Branch_NAME |
push | Default | feature-branch-name |
Case + chars normalized |
refs/heads/develop |
push | Default | develop |
Git prefix stripped |
very-long-branch-name-that-exceeds-limits |
push | Default | very-long-branch-name-that |
Truncated to 26 chars |
very-long-branch-name-that-exceeds-limits |
push | length: 15 |
very-long-branc |
Custom truncation |
123-very-long-name-exceeds-limits |
push | prefix: "issue-", length: 20 |
issue-123-very-long |
Custom prefix + truncation |
| No ref available | any | Any | Uses fallback stage | Error handling |
Error Handling:
- Missing Git reference → Uses provided fallback stage
- Invalid characters → Sanitized automatically
- Exceeds length → Truncated to 26 characters
- Starts with number → Prefixed with
pr- - GitHub context unavailable → Uses fallback with error status
- uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: staging
token: ${{ secrets.GITHUB_TOKEN }}- uses: kodehort/sst-operations-action@v1
with:
operation: diff
stage: production
token: ${{ secrets.GITHUB_TOKEN }}
comment-mode: always- uses: kodehort/sst-operations-action@v1
with:
operation: remove
stage: feature-branch
token: ${{ secrets.GITHUB_TOKEN }}- uses: kodehort/sst-operations-action@v1
with:
operation: stage
token: ${{ secrets.GITHUB_TOKEN }}- name: Deploy to Production
id: deploy
uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: production
token: ${{ secrets.GITHUB_TOKEN }}
comment-mode: never
fail-on-error: true
max-output-size: 100000
- name: Validate Deployment
run: |
if [ "${{ steps.deploy.outputs.success }}" = "true" ]; then
echo "✅ Deployment successful"
echo "Outputs: ${{ steps.deploy.outputs.outputs }}"
echo "Resources changed: ${{ steps.deploy.outputs.resource_changes }}"
# Run health checks
URLS=$(echo '${{ steps.deploy.outputs.outputs }}' | jq -r '.[].value | select(type == "string" and startswith("http"))')
for url in $URLS; do
echo "Testing: $url"
curl -f "$url/health" || exit 1
done
else
echo "❌ Deployment failed"
echo "Status: ${{ steps.deploy.outputs.completion_status }}"
exit 1
fi- name: Conditional Deploy
uses: kodehort/sst-operations-action@v1
with:
operation: ${{ github.event_name == 'pull_request' && 'diff' || 'deploy' }}
stage: ${{ github.event_name == 'pull_request' && 'staging' || 'production' }}
token: ${{ secrets.GITHUB_TOKEN }}
comment-mode: ${{ github.event_name == 'pull_request' && 'always' || 'on-failure' }}- name: Deploy to Staging
id: staging
uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: staging
token: ${{ secrets.GITHUB_TOKEN }}
- name: Run Integration Tests
run: |
# Integration tests against staging
npm run test:integration
- name: Deploy to Production
if: steps.staging.outputs.success == 'true'
uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: production
token: ${{ secrets.GITHUB_TOKEN }}- name: Calculate Dynamic Stage
id: stage-calc
uses: kodehort/sst-operations-action@v1
with:
operation: stage
token: ${{ secrets.GITHUB_TOKEN }}
stage: development # Fallback for edge cases
truncation-length: 20 # Shorter stage names
prefix: ticket- # Custom prefix for ticket integration
- name: Conditional Deploy Based on Stage
uses: kodehort/sst-operations-action@v1
with:
operation: ${{ steps.stage-calc.outputs.is_pull_request == 'true' && 'diff' || 'deploy' }}
stage: ${{ steps.stage-calc.outputs.computed_stage }}
token: ${{ secrets.GITHUB_TOKEN }}
comment-mode: ${{ steps.stage-calc.outputs.is_pull_request == 'true' && 'always' || 'on-failure' }}
- name: Cleanup Preview Environments
if: |
github.event_name == 'pull_request' &&
github.event.action == 'closed' &&
steps.stage-calc.outputs.is_pull_request == 'true'
uses: kodehort/sst-operations-action@v1
with:
operation: remove
stage: ${{ steps.stage-calc.outputs.computed_stage }}
token: ${{ secrets.GITHUB_TOKEN }}
fail-on-error: false # Allow partial cleanup- name: Calculate Route53-Safe Stage
id: route53-stage
uses: kodehort/sst-operations-action@v1
with:
operation: stage
token: ${{ secrets.GITHUB_TOKEN }}
truncation-length: 26 # Route53 subdomain limit
prefix: env- # Ensure valid DNS names
stage: default # Fallback stage
- name: Deploy with Route53-Safe Stage
uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: ${{ steps.route53-stage.outputs.computed_stage }}
token: ${{ secrets.GITHUB_TOKEN }}- name: Calculate Short Stage Name
id: short-stage
uses: kodehort/sst-operations-action@v1
with:
operation: stage
token: ${{ secrets.GITHUB_TOKEN }}
truncation-length: 12 # Very short stages
prefix: "" # No prefix for maximum brevity
stage: dev # Short fallbackThe action categorizes errors for better handling and recovery:
Error: SST command failed with exit code 1
Cause: SST CLI command failed
Recovery: Check SST configuration and AWS credentials
Error: Invalid operation: "deployment"
Cause: Invalid input parameters
Recovery: Correct input values
Warning: Failed to parse deployment URLs
Cause: Unexpected SST output format
Recovery: Operation may succeed but outputs incomplete
Error: Bad credentials
Cause: Invalid or insufficient GitHub token
Recovery: Check token permissions
When operations fail, outputs are still populated with available information:
# Failed operation outputs
success: "false"
operation: "deploy"
stage: "staging"
app: "my-app"
completion_status: "failed"
resource_changes: "0"
outputs: "[]"
resources: "[]"
error: "Deployment failed: <reason>"
truncated: "false"
permalink: ""- name: Deploy
uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: production
token: ${{ secrets.GITHUB_TOKEN }}
fail-on-error: true # Fail immediately on error- name: Optional Deploy
id: deploy
uses: kodehort/sst-operations-action@v1
with:
operation: deploy
stage: staging
token: ${{ secrets.GITHUB_TOKEN }}
fail-on-error: false
- name: Handle Deploy Result
run: |
if [ "${{ steps.deploy.outputs.success }}" = "false" ]; then
echo "Deploy failed, continuing with alternatives"
# Alternative logic here
fi- name: Deploy with Retry
uses: nick-invision/retry@v2
with:
timeout_minutes: 10
max_attempts: 3
retry_on: error
command: |
# Use the action within retry logic
echo "Attempting deployment..."The action respects several environment variables for configuration:
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: us-east-1
AWS_DEFAULT_REGION: us-east-1env:
SST_TELEMETRY_DISABLED: "1" # Disable telemetry
SST_DEBUG: "1" # Enable debug mode
SST_STAGE: staging # Default stage (overridden by input)env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ACTIONS_STEP_DEBUG: true # Enable debug loggingenv:
NODE_ENV: production
CI: true
FORCE_COLOR: "1" # Colorized outputThis API reference provides complete documentation for all aspects of the SST Operations Action. For additional examples and use cases, see the README.md and examples/ directory.