This section contains real world and common examples of how you could use this Action
Note: In all examples, we will be using
uses: github/[email protected]
. ReplaceX.X.X
with the latest version of this Action
Quick links below to jump to a specific branch-deploy example:
This is the simplest possible example of how you could use the branch-deploy Action for reference
.deploy noop
has no effect here (but you could change that).deploy
will deploy the current branch (you can configure deployments however you like, this is just an example)
name: branch-deploy
on:
issue_comment:
types: [created]
# Permissions needed for reacting and adding comments for IssueOps commands
permissions:
pull-requests: write
deployments: write
contents: write
checks: read
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
if: ${{ github.event.issue.pull_request }} # only run on pull request comments
steps:
# The branch-deploy Action
- name: branch-deploy
id: branch-deploy
uses: github/[email protected]
# If the branch-deploy Action was triggered, checkout our branch
- uses: actions/checkout@v3
with:
ref: ${{ steps.branch-deploy.outputs.ref }}
# If the branch-deploy Action was triggered, run the deployment (i.e. '.deploy')
- name: deploy
if: ${{ steps.branch-deploy.outputs.continue == 'true' && steps.branch-deploy.outputs.noop != 'true' }}
run: <do-your-deployment> # this could be anything you want
This example shows how you could use this Action with Terraform
.deploy noop
triggers a Terraform plan.deploy
triggers a Terraform apply
All deployment results get posted as a comment in the branch deploy output on your pull request
A live example can be found here
name: branch-deploy
on:
issue_comment:
types: [ created ]
# The working directory where our Terraform files are located
env:
WORKING_DIR: terraform/
# Permissions needed for reacting and adding comments for IssueOps commands
permissions:
pull-requests: write
deployments: write
contents: write
checks: read
jobs:
deploy:
name: deploy
runs-on: ubuntu-latest
if: ${{ github.event.issue.pull_request }} # only run on pull request comments
environment: production-secrets # the locked down environment we pull secrets from
defaults:
run:
working-directory: ${{ env.WORKING_DIR }} # the directory we use where all our TF files are stored
steps:
# The branch-deploy Action
- name: branch-deploy
id: branch-deploy
uses: github/[email protected]
# If the branch-deploy Action was triggered, checkout our branch
- name: Checkout
if: steps.branch-deploy.outputs.continue == 'true'
uses: actions/checkout@v3
with:
ref: ${{ steps.branch-deploy.outputs.ref }}
# Setup Terraform on our Actions runner
- uses: hashicorp/setup-terraform@ed3a0531877aca392eb870f440d9ae7aba83a6bd # pin@v1
if: steps.branch-deploy.outputs.continue == 'true'
with:
terraform_version: 1.1.7 # use the version of Terraform your project uses here
cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
# Run Terraform init in our working directory
- name: Terraform init
if: steps.branch-deploy.outputs.continue == 'true'
run: terraform init
# If '.deploy noop' was used, run a Terraform plan
- name: Terraform plan
if: ${{ steps.branch-deploy.outputs.continue == 'true' && steps.branch-deploy.outputs.noop == 'true' }}
id: plan
run: terraform plan -no-color
continue-on-error: true # continue on error as we will handle errors later on
# If '.deploy' was used, run a Terraform apply
- name: Terraform apply
if: ${{ steps.branch-deploy.outputs.continue == 'true' && steps.branch-deploy.outputs.noop != 'true' }}
id: apply
run: terraform apply -no-color -auto-approve
continue-on-error: true # continue on error as we will handle errors later on
# This step writes the TF plan/apply output to $GITHUB_ENV which the branch-deploy Action will read from and post as a comment on the pull request
- name: Terraform plan output
if: ${{ steps.branch-deploy.outputs.continue == 'true' && steps.branch-deploy.outputs.noop == 'true' }}
env:
TF_STDOUT: ${{ steps.plan.outputs.stdout }}
run: |
TF_OUTPUT="\`\`\`terraform\n${TF_STDOUT}\n\`\`\`"
echo 'DEPLOY_MESSAGE<<EOF' >> $GITHUB_ENV
echo "$TF_OUTPUT" >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
- name: Terraform apply output
if: ${{ steps.branch-deploy.outputs.continue == 'true' && steps.branch-deploy.outputs.noop != 'true' }}
env:
TF_STDOUT: ${{ steps.apply.outputs.stdout }}
run: |
TF_OUTPUT="\`\`\`terraform\n${TF_STDOUT}\n\`\`\`"
echo 'DEPLOY_MESSAGE<<EOF' >> $GITHUB_ENV
echo "$TF_OUTPUT" >> $GITHUB_ENV
echo 'EOF' >> $GITHUB_ENV
# Here we handle any errors that might have occurred during the Terraform plan/apply and exit accordingly
- name: Check Terraform plan output
if: ${{ steps.branch-deploy.outputs.continue == 'true' && steps.branch-deploy.outputs.noop == 'true' && steps.plan.outcome == 'failure' }}
run: exit 1
- name: Check Terraform apply output
if: ${{ steps.branch-deploy.outputs.continue == 'true' && steps.branch-deploy.outputs.noop != 'true' && steps.apply.outcome == 'failure' }}
run: exit 1
This example shows how you could use this Action with Heroku
.deploy noop
has no effect here (but you could change that).deploy
takes your current branch and deploys it to Heroku
A live example can be found here
name: branch-deploy
on:
issue_comment:
types: [ created ]
permissions:
pull-requests: write
deployments: write
contents: write
checks: read
jobs:
deploy:
name: deploy
if: ${{ github.event.issue.pull_request }} # only run on pull request comments
runs-on: ubuntu-latest
environment: production-secrets # the locked down environment we pull secrets from
steps:
# The branch-deploy Action
- name: branch-deploy
id: branch-deploy
uses: github/[email protected]
# If the branch-deploy Action was triggered, checkout our branch
- name: Checkout
if: steps.branch-deploy.outputs.continue == 'true'
uses: actions/checkout@v3
with:
ref: ${{ steps.branch-deploy.outputs.ref }}
# Deploy our branch to Heroku
- name: Deploy to Heroku
if: steps.branch-deploy.outputs.continue == 'true'
uses: AkhileshNS/heroku-deploy@79ef2ae4ff9b897010907016b268fd0f88561820 # [email protected]
with:
heroku_app_name: <your-heroku-app-name-here>
heroku_email: ${{ secrets.HEROKU_EMAIL }}
heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
This example shows how you could use this Action with Railway
.deploy noop
has no effect here (but you could change that).deploy
takes your current branch and deploys it to Railway
A live example can be found here
name: branch-deploy
on:
issue_comment:
types: [ created ]
permissions:
pull-requests: write
deployments: write
contents: write
checks: read
jobs:
deploy:
name: deploy
if: ${{ github.event.issue.pull_request }} # only run on pull request comments
runs-on: ubuntu-latest
environment: production-secrets # the locked down environment we pull secrets from
steps:
# The branch-deploy Action
- name: branch-deploy
id: branch-deploy
uses: github/[email protected]
# If the branch-deploy Action was triggered, checkout our branch
- name: Checkout
if: steps.branch-deploy.outputs.continue == 'true'
uses: actions/checkout@v3
with:
ref: ${{ steps.branch-deploy.outputs.ref }}
# Install the Railway CLI through npm
- name: Install Railway
run: npm i -g @railway/cli
# Deploy our branch to Railway
- name: Deploy to Railway
if: steps.branch-deploy.outputs.continue == 'true'
run: railway up
env:
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
This example shows how you could use this Action with SSH
You can define any commands you want to be run in your SSH Action and they would be gated by the branch-deploy Action.
.deploy noop
has no effect here (but you could change that).deploy
runs the SSH action with your branch
A live example can be found here
name: branch-deploy
on:
issue_comment:
types: [created]
# Permissions needed for reacting and adding comments for IssueOps commands
permissions:
pull-requests: write
deployments: write
contents: write
checks: read
jobs:
deploy:
environment: production-secrets # the locked down environment we pull secrets from
if: ${{ github.event.issue.pull_request }} # only run on pull request comments
runs-on: ubuntu-latest
steps:
# The branch-deploy Action
- uses: github/[email protected]
id: branch-deploy
# If the branch-deploy Action was triggered, checkout our branch
- name: Checkout
if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
uses: actions/checkout@v3
with:
ref: ${{ steps.branch-deploy.outputs.ref }}
# Deploy our branch via SSH remote commands
- name: SSH Remote Deploy
if: ${{ steps.branch-deploy.outputs.continue == 'true' && steps.branch-deploy.outputs.noop != 'true' }}
uses: appleboy/ssh-action@1d1b21ca96111b1eb4c03c21c14ebb971d2200f6 # [email protected]
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.SSH_PORT }}
script_stop: true
script: <run-some-ssh-commands-here> # this could be whatever you want
This example shows how you could use this Action with Cloudflare Pages
.deploy to development
deploys your branch to the development environment.deploy
deploys your branch to the production environment
A live example can be found here
name: branch-deploy
on:
issue_comment:
types: [ created ]
# Permissions needed for reacting and adding comments for IssueOps commands
permissions:
pull-requests: write
deployments: write
contents: write
checks: read
jobs:
deploy:
environment: secrets # the locked down environment we pull secrets from
if: ${{ github.event.issue.pull_request }} # only run on pull request comments
runs-on: ubuntu-latest
steps:
# The branch-deploy Action
- uses: github/[email protected]
id: branch-deploy
# If the branch-deploy Action was triggered, checkout our branch
- name: Checkout
if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
uses: actions/checkout@v3
with:
ref: ${{ steps.branch-deploy.outputs.ref }}
# Install the npm dependencies to build our cloudflare pages site
- name: Install
if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
run: npm ci
# Build our cloudflare pages site
- name: Build
if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
run: npm run build
# If '.deploy to development' was used, branch deploy to the development environment
- name: deploy - dev
id: dev-deploy
if: ${{ steps.branch-deploy.outputs.continue == 'true' && steps.branch-deploy.outputs.noop != 'true' && steps.branch-deploy.outputs.environment == 'development' }}
uses: cloudflare/wrangler-action@4c10c1822abba527d820b29e6333e7f5dac2cabd # [email protected]
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
accountId: ${{ secrets.CF_ACCOUNT_ID }}
command: pages publish build/ --project-name=<your-cloudflare-project-name>
# If '.deploy' was used, branch deploy to the production environment
- name: deploy - prod
id: prod-deploy
if: ${{ steps.branch-deploy.outputs.continue == 'true' && steps.branch-deploy.outputs.noop != 'true' && steps.branch-deploy.outputs.environment == 'production' }}
uses: cloudflare/wrangler-action@4c10c1822abba527d820b29e6333e7f5dac2cabd # [email protected]
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
accountId: ${{ secrets.CF_ACCOUNT_ID }}
command: pages publish build/ --project-name=<your-cloudflare-project-name> --branch=main
This example shows how you could use this Action with Cloudflare Workers
.deploy to development
deploys your branch to the development environment (if you have one with your Cloudflare workers).deploy
deploys your branch to the production environment
A live example can be found here
name: branch-deploy
on:
issue_comment:
types: [ created ]
# Permissions needed for reacting and adding comments for IssueOps commands
permissions:
pull-requests: write
deployments: write
contents: write
checks: read
jobs:
deploy:
environment: secrets # the locked down environment we pull secrets from
if: ${{ github.event.issue.pull_request }} # only run on pull request comments
runs-on: ubuntu-latest
steps:
# The branch-deploy Action
- uses: github/[email protected]
id: branch-deploy
# If the branch-deploy Action was triggered, checkout our branch
- name: Checkout
if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
uses: actions/checkout@v3
with:
ref: ${{ steps.branch-deploy.outputs.ref }}
# Install the npm dependencies for your cloudflare workers project
# Most importantly, we need to install @cloudflare/wrangler
- name: Install dependencies
if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
run: npm ci
# If '.deploy to development' was used, branch deploy to the development environment
- name: Publish - Development
if: ${{ steps.branch-deploy.outputs.environment == 'development' &&
steps.branch-deploy.outputs.noop != 'true' &&
steps.branch-deploy.outputs.continue == 'true' }}
uses: cloudflare/wrangler-action@3424d15af26edad39d5276be3cc0cc9ffec22b55 # [email protected]
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
environment: "development" # here we use development
# If '.deploy' was used, branch deploy to the production environment
- name: Publish - Production
if: ${{ steps.branch-deploy.outputs.continue == 'true' &&
steps.branch-deploy.outputs.noop != 'true' &&
steps.branch-deploy.outputs.environment == 'production' }}
uses: cloudflare/wrangler-action@3424d15af26edad39d5276be3cc0cc9ffec22b55 # [email protected]
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
If you need a complex deployment workflow, you can create a deployment status manually in a separate step
This is a more advanced example
name: deploy
on:
issue_comment:
types: [created]
permissions:
pull-requests: write
deployments: write
contents: write
checks: read
jobs:
trigger:
if: ${{ github.event.issue.pull_request }} # only run on pull request comments
runs-on: ubuntu-latest
outputs:
continue: ${{ steps.branch-deploy.outputs.continue }}
noop: ${{ steps.branch-deploy.outputs.noop }}
deployment_id: ${{ steps.branch-deploy.outputs.deployment_id }}
environment: ${{ steps.branch-deploy.outputs.environment }}
ref: ${{ steps.branch-deploy.outputs.ref }}
comment_id: ${{ steps.branch-deploy.outputs.comment_id }}
initial_reaction_id: ${{ steps.branch-deploy.outputs.initial_reaction_id }}
actor_handle: ${{ steps.branch-deploy.outputs.actor_handle }}
steps:
- uses: github/[email protected]
id: branch-deploy
with:
skip_completing: 'true' # we will complete the deployment manually
deploy:
needs: trigger
if: ${{ needs.trigger.outputs.continue == 'true' && needs.trigger.outputs.noop != 'true' }}
runs-on: ubuntu-latest
steps:
# checkout the project's repository based on the ref provided by the branch-deploy step
- name: checkout
uses: actions/checkout@v3
with:
ref: ${{ needs.trigger.outputs.ref }}
# You will do your own deployment here
- name: fake regular deploy
run: echo "I am doing a fake regular deploy"
# update the deployment result - manually complete the deployment that was created by the branch-deploy action
result:
needs: [trigger, deploy]
runs-on: ubuntu-latest
# run even on failures but only if the trigger job set continue to true
if: ${{ always() && needs.trigger.outputs.continue == 'true' }}
steps:
# if a previous step failed, set a variable to use as the deployment status
- name: set deployment status
id: deploy-status
if: ${{ needs.trigger.result == 'failure' || needs.deploy.result == 'failure' }}
run: |
echo "DEPLOY_STATUS=failure" >> $GITHUB_OUTPUT
# use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action
- name: Create a deployment status
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
DEPLOY_STATUS: ${{ steps.deploy-status.outputs.DEPLOY_STATUS }}
run: |
if [ -z "${DEPLOY_STATUS}" ]; then
DEPLOY_STATUS="success"
fi
gh api \
--method POST \
repos/{owner}/{repo}/deployments/${{ needs.trigger.outputs.deployment_id }}/statuses \
-f environment='${{ needs.trigger.outputs.environment }}' \
-f state=${DEPLOY_STATUS}
# use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action
- name: Remove a non-sticky lock
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
run: |
gh api \
--method DELETE \
repos/{owner}/{repo}/git/refs/heads/${{ needs.trigger.outputs.environment }}-branch-deploy-lock
# remove the default 'eyes' reaction from the comment that triggered the deployment
# this reaction is added by the branch-deploy action by default
- name: remove eyes reaction
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
run: |
gh api \
--method DELETE \
repos/{owner}/{repo}/issues/comments/${{ needs.trigger.outputs.comment_id }}/reactions/${{ needs.trigger.outputs.initial_reaction_id }}
# if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment
- name: rocket reaction
if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}
uses: GrantBirki/comment@1e9986de26cf23e6c4350276234c91705c540fef # [email protected]
with:
comment-id: ${{ needs.trigger.outputs.comment_id }}
reactions: rocket
# if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment
- name: failure reaction
if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}
uses: GrantBirki/comment@1e9986de26cf23e6c4350276234c91705c540fef # [email protected]
with:
comment-id: ${{ needs.trigger.outputs.comment_id }}
reactions: "-1"
# if the deployment was successful, add a 'success' comment
- name: success comment
if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}
uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # [email protected]
with:
issue-number: ${{ github.event.issue.number }}
body: |
### Deployment Results ✅
**${{ needs.trigger.outputs.actor_handle }}** successfully deployed branch `${{ needs.trigger.outputs.ref }}` to **${{ needs.trigger.outputs.environment }}**
# if the deployment was not successful, add a 'failure' comment
- name: failure comment
if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}
uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # [email protected]
with:
issue-number: ${{ github.event.issue.number }}
body: |
### Deployment Results ❌
**${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.ref }}` to **${{ needs.trigger.outputs.environment }}**
A detailed example using multiple jobs, custom deployment status creation, non-sticky lock removal, and comments. This example showcases building a static site with hugo and deploying it to GitHub Pages.
This live example can be found here
name: branch deploy
# The workflow to execute on is comments that are newly created
on:
issue_comment:
types: [ created ]
# Permissions needed for reacting and adding comments for IssueOps commands
permissions:
pull-requests: write
deployments: write
contents: write
checks: read
pages: write
id-token: write
# set an environment variable for use in the jobs pointing to my blog
env:
blog_url: https://test.example.com # <--- CHANGE THIS TO YOUR BLOG URL
jobs:
# branch-deploy trigger job
trigger:
if: # only run on pull request comments and very specific comment body string as defined in our branch-deploy settings
${{ github.event.issue.pull_request &&
(contains(github.event.comment.body, '.deploy') ||
contains(github.event.comment.body, '.lock') ||
contains(github.event.comment.body, '.wcid') ||
contains(github.event.comment.body, '.unlock')) }}
runs-on: ubuntu-latest
outputs: # set outputs for use in downstream jobs
continue: ${{ steps.branch-deploy.outputs.continue }}
noop: ${{ steps.branch-deploy.outputs.noop }}
deployment_id: ${{ steps.branch-deploy.outputs.deployment_id }}
environment: ${{ steps.branch-deploy.outputs.environment }}
ref: ${{ steps.branch-deploy.outputs.ref }}
comment_id: ${{ steps.branch-deploy.outputs.comment_id }}
initial_reaction_id: ${{ steps.branch-deploy.outputs.initial_reaction_id }}
actor_handle: ${{ steps.branch-deploy.outputs.actor_handle }}
steps:
# execute the branch-deploy action
- uses: github/[email protected]
id: branch-deploy
with:
trigger: ".deploy"
environment: "github-pages"
production_environment: "github-pages"
skip_completing: "true" # we will complete the deployment manually in the 'result' job
admins: "false" # <--- add your GitHub username here (if you want to use the admins feature)
# build the github-pages site with hugo
build:
needs: trigger
if: ${{ needs.trigger.outputs.continue == 'true' }} # only run if the trigger job set continue to true
runs-on: ubuntu-latest
steps:
# checkout the project's repository based on the ref provided by the branch-deploy step
- name: checkout
uses: actions/checkout@v3
with:
ref: ${{ needs.trigger.outputs.ref }}
# read the hugo version from the .hugo-version file in this repository
- name: set hugo version
id: hugo-version
run: |
HUGO_VERSION=$(cat .hugo-version)
echo "HUGO_VERSION=${HUGO_VERSION}" >> $GITHUB_OUTPUT
# install the hugo cli using the version detected in the previous step
- name: install hugo cli
env:
HUGO_VERSION: ${{ steps.hugo-version.outputs.HUGO_VERSION }}
run: |
wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-amd64.deb \
&& sudo dpkg -i ${{ runner.temp }}/hugo.deb
# configure the GitHub Pages action
- name: setup pages
id: pages
uses: actions/configure-pages@c5a3e1159e0cbdf0845eb8811bd39e39fc3099c2 # [email protected]
# build the site with hugo
- name: build with hugo
run: |
hugo --gc --verbose \
--baseURL ${{ steps.pages.outputs.base_url }}
# this step is custom to my blog and adds a 'commit' version to the site
- name: write build version
run: echo ${GITHUB_SHA} > ./public/version.txt
# upload the built site as an artifact for the deploy step
- name: upload artifact
uses: actions/upload-pages-artifact@253fd476ed429e83b7aae64a92a75b4ceb1a17cf # [email protected]
with:
path: ./public
# deploy to GitHub Pages
deploy:
needs: [ trigger, build ]
if: ${{ needs.trigger.outputs.continue == 'true' }} # only run if the trigger job set continue to true
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
# deploy the site to GitHub Pages
- name: deploy
id: deployment
uses: actions/deploy-pages@20a4baa1095bad40ba7d6ca0d9abbc220b76603f # [email protected]
# update the deployment result - manually complete the deployment that was created by the branch-deploy action
result:
needs: [ trigger, build, deploy ]
runs-on: ubuntu-latest
# run even on failures but only if the trigger job set continue to true
if: ${{ always() && needs.trigger.outputs.continue == 'true' }}
steps:
# if a previous step failed, set a variable to use as the deployment status
- name: set deployment status
id: deploy-status
if: ${{ needs.trigger.result == 'failure' || needs.build.result == 'failure' ||
needs.deploy.result == 'failure' }}
run: |
echo "DEPLOY_STATUS=failure" >> $GITHUB_OUTPUT
# use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action
- name: Create a deployment status
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
DEPLOY_STATUS: ${{ steps.deploy-status.outputs.DEPLOY_STATUS }}
run: |
if [ -z "${DEPLOY_STATUS}" ]; then
DEPLOY_STATUS="success"
fi
gh api \
--method POST \
repos/{owner}/{repo}/deployments/${{ needs.trigger.outputs.deployment_id }}/statuses \
-f environment='${{ needs.trigger.outputs.environment }}' \
-f state=${DEPLOY_STATUS}
# use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action
- name: Remove a non-sticky lock
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
run: |
gh api \
--method DELETE \
repos/{owner}/{repo}/git/refs/heads/${{ needs.trigger.outputs.environment }}-branch-deploy-lock
# remove the default 'eyes' reaction from the comment that triggered the deployment
# this reaction is added by the branch-deploy action by default
- name: remove eyes reaction
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
run: |
gh api \
--method DELETE \
repos/{owner}/{repo}/issues/comments/${{ needs.trigger.outputs.comment_id }}/reactions/${{ needs.trigger.outputs.initial_reaction_id }}
# if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment
- name: rocket reaction
if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}
uses: GrantBirki/comment@1e9986de26cf23e6c4350276234c91705c540fef # [email protected]
with:
comment-id: ${{ needs.trigger.outputs.comment_id }}
reactions: rocket
# if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment
- name: failure reaction
if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}
uses: GrantBirki/comment@1e9986de26cf23e6c4350276234c91705c540fef # [email protected]
with:
comment-id: ${{ needs.trigger.outputs.comment_id }}
reactions: "-1"
# if the deployment was successful, add a 'success' comment
- name: success comment
if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}
uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # [email protected]
with:
issue-number: ${{ github.event.issue.number }}
body: |
### Deployment Results ✅
**${{ needs.trigger.outputs.actor_handle }}** successfully deployed branch `${{ needs.trigger.outputs.ref }}` to **${{ needs.trigger.outputs.environment }}**
> [View Live Deployment](${{ env.blog_url }}) :link:
# if the deployment was not successful, add a 'failure' comment
- name: failure comment
if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}
uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # [email protected]
with:
issue-number: ${{ github.event.issue.number }}
body: |
### Deployment Results ❌
**${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.ref }}` to **${{ needs.trigger.outputs.environment }}**
A detailed example using multiple jobs, custom deployment status creation, non-sticky lock removal, and comments - Using Astro to create a static site and deploying to GitHub Pages
A live example can be found here
name: branch deploy
# The workflow to execute on is comments that are newly created
on:
issue_comment:
types: [ created ]
# Permissions needed for reacting and adding comments for IssueOps commands
permissions:
pull-requests: write
deployments: write
contents: write
checks: read
pages: write
id-token: write
# set an environment variable for use in the jobs pointing the site_url
env:
site_url: https://test.example.com # <--- change this to your site url
jobs:
# branch-deploy trigger job
trigger:
if: # only run on pull request comments and very specific comment body string as defined in our branch-deploy settings
${{ github.event.issue.pull_request &&
(contains(github.event.comment.body, '.deploy') ||
contains(github.event.comment.body, '.lock') ||
contains(github.event.comment.body, '.wcid') ||
contains(github.event.comment.body, '.unlock')) }}
runs-on: ubuntu-latest
outputs: # set outputs for use in downstream jobs
continue: ${{ steps.branch-deploy.outputs.continue }}
noop: ${{ steps.branch-deploy.outputs.noop }}
deployment_id: ${{ steps.branch-deploy.outputs.deployment_id }}
environment: ${{ steps.branch-deploy.outputs.environment }}
ref: ${{ steps.branch-deploy.outputs.ref }}
comment_id: ${{ steps.branch-deploy.outputs.comment_id }}
initial_reaction_id: ${{ steps.branch-deploy.outputs.initial_reaction_id }}
actor_handle: ${{ steps.branch-deploy.outputs.actor_handle }}
steps:
# execute the branch-deploy action
- uses: github/[email protected]
id: branch-deploy
with:
trigger: ".deploy"
environment: "github-pages"
production_environment: "github-pages"
environment_targets: "github-pages"
skip_completing: "true" # we will complete the deployment manually in the 'result' job
admins: "false" # <--- add your GitHub username here (if you want to use the admins feature)
# build the github-pages site with hugo
build:
needs: trigger
if: ${{ needs.trigger.outputs.continue == 'true' }} # only run if the trigger job set continue to true
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v3
with:
ref: ${{ needs.trigger.outputs.ref }}
- name: build with astro
uses: withastro/action@dc081df9eacdb11181ea51e5d05853faa5aee891 # [email protected]
# deploy to GitHub Pages
deploy:
needs: [ trigger, build ]
if: ${{ needs.trigger.outputs.continue == 'true' }} # only run if the trigger job set continue to true
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
# deploy the site to GitHub Pages
- name: deploy
id: deployment
uses: actions/deploy-pages@497da40f5225e762159b457c9ae5d6f75a136f5c # [email protected]
# update the deployment result - manually complete the deployment that was created by the branch-deploy action
result:
needs: [ trigger, build, deploy ]
runs-on: ubuntu-latest
# run even on failures but only if the trigger job set continue to true
if: ${{ always() && needs.trigger.outputs.continue == 'true' }}
steps:
# if a previous step failed, set a variable to use as the deployment status
- name: set deployment status
id: deploy-status
if: ${{ needs.trigger.result == 'failure' || needs.build.result == 'failure' ||
needs.deploy.result == 'failure' }}
run: |
echo "DEPLOY_STATUS=failure" >> $GITHUB_OUTPUT
# use the GitHub CLI to update the deployment status that was initiated by the branch-deploy action
- name: Create a deployment status
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
DEPLOY_STATUS: ${{ steps.deploy-status.outputs.DEPLOY_STATUS }}
run: |
if [ -z "${DEPLOY_STATUS}" ]; then
DEPLOY_STATUS="success"
fi
gh api \
--method POST \
repos/{owner}/{repo}/deployments/${{ needs.trigger.outputs.deployment_id }}/statuses \
-f environment='${{ needs.trigger.outputs.environment }}' \
-f state=${DEPLOY_STATUS}
# use the GitHub CLI to remove the non-sticky lock that was created by the branch-deploy action
- name: Remove a non-sticky lock
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
run: |
gh api \
--method DELETE \
repos/{owner}/{repo}/git/refs/heads/${{ needs.trigger.outputs.environment }}-branch-deploy-lock
# remove the default 'eyes' reaction from the comment that triggered the deployment
# this reaction is added by the branch-deploy action by default
- name: remove eyes reaction
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
run: |
gh api \
--method DELETE \
repos/{owner}/{repo}/issues/comments/${{ needs.trigger.outputs.comment_id }}/reactions/${{ needs.trigger.outputs.initial_reaction_id }}
# if the deployment was successful, add a 'rocket' reaction to the comment that triggered the deployment
- name: rocket reaction
if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}
uses: GrantBirki/comment@1e9986de26cf23e6c4350276234c91705c540fef # [email protected]
with:
comment-id: ${{ needs.trigger.outputs.comment_id }}
reactions: rocket
# if the deployment failed, add a '-1' (thumbs down) reaction to the comment that triggered the deployment
- name: failure reaction
if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}
uses: GrantBirki/comment@1e9986de26cf23e6c4350276234c91705c540fef # [email protected]
with:
comment-id: ${{ needs.trigger.outputs.comment_id }}
reactions: "-1"
# if the deployment was successful, add a 'success' comment
- name: success comment
if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS != 'failure' }}
uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # [email protected]
with:
issue-number: ${{ github.event.issue.number }}
body: |
### Deployment Results ✅
**${{ needs.trigger.outputs.actor_handle }}** successfully deployed branch `${{ needs.trigger.outputs.ref }}` to **${{ needs.trigger.outputs.environment }}**
> [View Live Deployment](${{ env.site_url }}) :link:
# if the deployment was not successful, add a 'failure' comment
- name: failure comment
if: ${{ steps.deploy-status.outputs.DEPLOY_STATUS == 'failure' }}
uses: peter-evans/create-or-update-comment@67dcc547d311b736a8e6c5c236542148a47adc3d # [email protected]
with:
issue-number: ${{ github.event.issue.number }}
body: |
### Deployment Results ❌
**${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.ref }}` to **${{ needs.trigger.outputs.environment }}**
Are you using the branch-deploy
Action and want your example included here? Open a pull request and we'll add it!