Skip to content

Commit

Permalink
update and replace all documentation references of `steps.branch-depl…
Browse files Browse the repository at this point in the history
…oy.outputs.ref` to `steps.branch-deploy.outputs.sha` - also adds docs
  • Loading branch information
GrantBirki committed Dec 5, 2024
1 parent 7745922 commit 8809251
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 29 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/old/sample-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
# - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # pin@v3.0.2
# if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
# with:
# ref: ${{ steps.branch-deploy.outputs.ref }}
# ref: ${{ steps.branch-deploy.outputs.sha }}

# # Do some fake "noop" deployment logic here
# - name: fake noop deploy
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,11 @@ jobs:

# Run your deployment logic for your project here - examples seen below

# Checkout your projects repository based on the ref provided by the branch-deploy step
# Checkout your project's repository based on the commit SHA provided by the branch-deploy step
# It is important to only ever operate on the commit SHA (where possible) as commit SHA's are immutable and you know exactly what you are deploying
- uses: actions/checkout@v4
with:
ref: ${{ steps.branch-deploy.outputs.ref }}
ref: ${{ steps.branch-deploy.outputs.sha }}

# Do some fake "noop" deployment logic here
# conditionally run a noop deployment
Expand Down
75 changes: 75 additions & 0 deletions docs/deploying-commit-SHAs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Deploying Commit SHAs

## TL;DR

Instead of this:

```yaml
- name: branch-deploy
id: branch-deploy
uses: github/branch-deploy@vX.X.X

- name: checkout
if: steps.branch-deploy.outputs.continue == 'true'
uses: actions/checkout@v4
with:
ref: ${{ steps.branch-deploy.outputs.ref }} # <-- This is the branch name, can be risky
```
Do this:
```yaml
- name: branch-deploy
id: branch-deploy
uses: github/branch-deploy@vX.X.X

- name: checkout
if: steps.branch-deploy.outputs.continue == 'true'
uses: actions/checkout@v4
with:
ref: ${{ steps.branch-deploy.outputs.sha }} # <-- uses an exact commit SHA - safe!
```
This ensures you are deploying the __exact__ commit SHA that branch-deploy has determined is safe to deploy. This is a best practice for security, reliability, and safety during deployments.
## Introduction
Deploying commit SHAs (Secure Hash Algorithms) is a best practice in software development and deployment processes. This document explains the importance of deploying commit SHAs, focusing on aspects of security, reliability, and safety. It also provides an overview of how commit SHAs work under the hood in Git and how this contributes to the overall safety of the deployment process.
## Importance of Deploying Commit SHAs
### Security
1. Immutable References: Commit SHAs are immutable references to specific states of the codebase. Once a commit is created, its SHA cannot be changed. This ensures that the exact code being deployed is known and cannot be altered without changing the SHA.
2. Verification: Using commit SHAs allows for the verification of the code being deployed. Security tools can check the integrity of the code by comparing the SHA of the deployed code with the expected SHA. Commits can be signed with GPG keys to further enhance security.
3. Auditability: Deploying specific commit SHAs provides a clear audit trail. It is easy to track which code was deployed and when, making it easier to investigate and resolve security incidents.
### Reliability
1. Consistency: Deploying commit SHAs ensures that the same code is deployed across different environments (e.g., staging, production). This consistency reduces the risk of discrepancies and bugs that may arise from deploying different versions of the code.
2. Reproducibility: With commit SHAs, deployments are reproducible. If an issue arises, it is possible to redeploy the exact same code by referencing the same SHA, ensuring that the environment is identical to the previous deployment.
3. Rollback: In case of a failure, rolling back to a previous commit SHA is straightforward. This allows for quick recovery and minimizes downtime. In the context of this project, it is best to deploy the `main` (stable) branch during rollbacks. However, this project does support deploying specific commit SHAs through the [`allow_sha_deployments`](./sha-deployments.md) input option.

### Safety

1. Atomic Changes: Each commit SHA represents an atomic change to the codebase. Deploying commit SHAs ensures that all changes in a commit are deployed together, reducing the risk of partial deployments that can lead to inconsistencies.
2. Isolation: Commit SHAs isolate changes, making it easier to identify and isolate issues. If a deployment fails, it is easier to pinpoint the problematic commit and address the issue. For example, if a specific commit introduces a bug, rolling back to the previous commit SHA can resolve the issue.
3. Predictability: Deploying commit SHAs provides predictability in the deployment process. Knowing exactly what code is being deployed reduces uncertainty and increases confidence in the deployment process.

## How Commit SHAs Work in Git

### Under the Hood

1. SHA-1 Hashing: Git uses the SHA-1 hashing algorithm to generate a unique identifier (SHA) for each commit. This SHA is a 40-character hexadecimal string that uniquely represents the commit.
2. Content-Based: The SHA is generated based on the content of the commit, including the changes made, the commit message, the author, and the timestamp. This ensures that even a small change in the commit will result in a different SHA.
3. Immutable: Once a commit is created, its SHA cannot be changed. This immutability ensures that the commit reference is stable and reliable.

## How Commits Compare to Branches or Tags

Branches and tags can be moved or updated to point to different commits. This mutability can lead to inconsistencies and unexpected changes in the deployed code. For this reason, deploying commit SHAs is preferred over deploying branches or tags. Now this might be somewhat confusing as the name of this project is `branch-deploy`. This is because at a high-level we are indeed deploying _branches_ but in reality, we are deploying the exact _commit_ that the branch points to. This is often the latest commit on the branch but it does not have to be based on the input options provided.

## Conclusion

Deploying commit SHAs is a best practice that enhances the security, reliability, and safety of the deployment process. By leveraging the immutable and content-based nature of commit SHAs, organizations can ensure that their deployments are consistent, reproducible, and traceable. Understanding how commit SHAs work under the hood in Git further underscores their importance in maintaining the integrity and stability of the codebase during deployments.

This Action will take care of all the heavy lifting for you under the hood when it comes to commits. It will set an output named `sha` on __every single deployment__ that will point to the exact commit SHA that you should utilize for your deployment process.
52 changes: 26 additions & 26 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
# If the branch-deploy Action was triggered, checkout our branch
- uses: actions/checkout@v4
with:
ref: ${{ steps.branch-deploy.outputs.ref }}
ref: ${{ steps.branch-deploy.outputs.sha }}

# If the branch-deploy Action was triggered, run the noop deployment (i.e. '.noop')
- name: noop deploy
Expand Down Expand Up @@ -123,7 +123,7 @@ jobs:
if: steps.branch-deploy.outputs.continue == 'true'
uses: actions/checkout@v4
with:
ref: ${{ steps.branch-deploy.outputs.ref }}
ref: ${{ steps.branch-deploy.outputs.sha }}
# Setup Terraform on our Actions runner
- uses: hashicorp/setup-terraform@ed3a0531877aca392eb870f440d9ae7aba83a6bd # pin@v1
Expand Down Expand Up @@ -222,7 +222,7 @@ jobs:
if: steps.branch-deploy.outputs.continue == 'true'
uses: actions/checkout@v4
with:
ref: ${{ steps.branch-deploy.outputs.ref }}
ref: ${{ steps.branch-deploy.outputs.sha }}
# Deploy our branch to Heroku
- name: Deploy to Heroku
Expand Down Expand Up @@ -275,7 +275,7 @@ jobs:
if: steps.branch-deploy.outputs.continue == 'true'
uses: actions/checkout@v4
with:
ref: ${{ steps.branch-deploy.outputs.ref }}
ref: ${{ steps.branch-deploy.outputs.sha }}
# Install the Railway CLI through npm
- name: Install Railway
Expand Down Expand Up @@ -331,7 +331,7 @@ jobs:
if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
uses: actions/checkout@v4
with:
ref: ${{ steps.branch-deploy.outputs.ref }}
ref: ${{ steps.branch-deploy.outputs.sha }}
# Deploy our branch via SSH remote commands
- name: SSH Remote Deploy
Expand Down Expand Up @@ -386,7 +386,7 @@ jobs:
if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
uses: actions/checkout@v4
with:
ref: ${{ steps.branch-deploy.outputs.ref }}
ref: ${{ steps.branch-deploy.outputs.sha }}
# setup node
- uses: actions/setup-node@v4
Expand Down Expand Up @@ -468,7 +468,7 @@ jobs:
if: ${{ steps.branch-deploy.outputs.continue == 'true' }}
uses: actions/checkout@v4
with:
ref: ${{ steps.branch-deploy.outputs.ref }}
ref: ${{ steps.branch-deploy.outputs.sha }}
# Install the npm dependencies for your cloudflare workers project
# Most importantly, we need to install @cloudflare/wrangler
Expand Down Expand Up @@ -527,7 +527,7 @@ jobs:
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 }}
sha: ${{ steps.branch-deploy.outputs.sha }}
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 }}
Expand All @@ -545,11 +545,11 @@ jobs:
runs-on: ubuntu-latest
steps:
# checkout the project's repository based on the ref provided by the branch-deploy step
# checkout the project's repository based on the commit SHA provided by the branch-deploy step
- name: checkout
uses: actions/checkout@v4
with:
ref: ${{ needs.trigger.outputs.ref }}
ref: ${{ needs.trigger.outputs.sha }}
# You will do your own deployment here
- name: fake regular deploy
Expand Down Expand Up @@ -650,7 +650,7 @@ jobs:
body: |
### Deployment Results ✅
**${{ needs.trigger.outputs.actor_handle }}** successfully deployed branch `${{ needs.trigger.outputs.ref }}` to **${{ needs.trigger.outputs.environment }}**
**${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**

# if the deployment was not successful, add a 'failure' comment
- name: failure comment
Expand All @@ -661,7 +661,7 @@ jobs:
body: |
### Deployment Results ❌
**${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.ref }}` to **${{ needs.trigger.outputs.environment }}**
**${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**
```
## Multiple Jobs with GitHub Pages and Hugo
Expand Down Expand Up @@ -707,7 +707,7 @@ jobs:
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 }}
sha: ${{ steps.branch-deploy.outputs.sha }}
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 }}
Expand All @@ -730,11 +730,11 @@ jobs:
runs-on: ubuntu-latest

steps:
# checkout the project's repository based on the ref provided by the branch-deploy step
# checkout the project's repository based on the commit SHA provided by the branch-deploy step
- name: checkout
uses: actions/checkout@v4
with:
ref: ${{ needs.trigger.outputs.ref }}
ref: ${{ needs.trigger.outputs.sha }}

# read the hugo version from the .hugo-version file in this repository
- name: set hugo version
Expand Down Expand Up @@ -884,7 +884,7 @@ jobs:
body: |
### Deployment Results ✅
**${{ needs.trigger.outputs.actor_handle }}** successfully deployed branch `${{ needs.trigger.outputs.ref }}` to **${{ needs.trigger.outputs.environment }}**
**${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**
> [View Live Deployment](${{ env.blog_url }}) :link:
Expand All @@ -897,7 +897,7 @@ jobs:
body: |
### Deployment Results ❌
**${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.ref }}` to **${{ needs.trigger.outputs.environment }}**
**${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**
```
## Multiple Jobs with GitHub Pages and Astro
Expand Down Expand Up @@ -945,7 +945,7 @@ jobs:
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 }}
sha: ${{ steps.branch-deploy.outputs.sha }}
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 }}
Expand All @@ -972,7 +972,7 @@ jobs:
- name: checkout
uses: actions/checkout@v4
with:
ref: ${{ needs.trigger.outputs.ref }}
ref: ${{ needs.trigger.outputs.sha }}

- name: build with astro
uses: withastro/action@e3193ac80e18917ceaeb9f2d47019ad3b2c0416a # pin@v0.3.0
Expand Down Expand Up @@ -1089,7 +1089,7 @@ jobs:
body: |
### Deployment Results ✅
**${{ needs.trigger.outputs.actor_handle }}** successfully deployed branch `${{ needs.trigger.outputs.ref }}` to **${{ needs.trigger.outputs.environment }}**
**${{ needs.trigger.outputs.actor_handle }}** successfully deployed `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**
> [View Live Deployment](${{ env.site_url }}) :link:
Expand All @@ -1102,7 +1102,7 @@ jobs:
body: |
### Deployment Results ❌
**${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.ref }}` to **${{ needs.trigger.outputs.environment }}**
**${{ needs.trigger.outputs.actor_handle }}** had a failure when deploying `${{ needs.trigger.outputs.sha }}` to **${{ needs.trigger.outputs.environment }}**
```
## Multiple Jobs with GitHub Environments
Expand Down Expand Up @@ -1146,7 +1146,7 @@ jobs:
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 }}
sha: ${{ steps.branch-deploy.outputs.sha }}
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 }}
Expand Down Expand Up @@ -1197,7 +1197,7 @@ jobs:
id: checkout
uses: actions/checkout@v4
with:
ref: ${{ needs.start.outputs.ref }}
ref: ${{ needs.start.outputs.sha }}

# Authenticate to Azure using OpenID Connect.
- name: Authenticate to Azure (OIDC)
Expand Down Expand Up @@ -1285,7 +1285,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
INITIAL_REACTION_ID: ${{ needs.start.outputs.initial_reaction_id }}
NOOP: ${{ needs.start.outputs.noop }}
REF: ${{ needs.start.outputs.ref }}
SHA: ${{ needs.start.outputs.sha }}
REPOSITORY: ${{ github.repository }}

steps:
Expand Down Expand Up @@ -1352,7 +1352,7 @@ jobs:
repo: context.repo.repo,
body: `### Deployment Results :white_check_mark:
**${{ env.ACTOR }}** successfully ${ process.env.NOOP === 'true' ? '**noop** deployed' : 'deployed' } branch \`${{ env.REF }}\` to **${{ env.ENVIRONMENT }}**
**${{ env.ACTOR }}** successfully ${ process.env.NOOP === 'true' ? '**noop** deployed' : 'deployed' } sha \`${{ env.SHA }}\` to **${{ env.ENVIRONMENT }}**
<details><summary>Show Results</summary>
Expand Down Expand Up @@ -1380,7 +1380,7 @@ jobs:
repo: context.repo.repo,
body: `### Deployment Results :x:
**${{ env.ACTOR }}** had a failure when ${ process.env.NOOP === 'true' ? '**noop** deploying' : 'deploying' } branch \`${{ env.REF }}\` to **${{ env.ENVIRONMENT }}**
**${{ env.ACTOR }}** had a failure when ${ process.env.NOOP === 'true' ? '**noop** deploying' : 'deploying' } sha \`${{ env.SHA }}\` to **${{ env.ENVIRONMENT }}**
<details><summary>Show Results</summary>
Expand Down

0 comments on commit 8809251

Please sign in to comment.