Skip to content

Commit c23b24d

Browse files
authored
[BRE-1374] Creating Template structure and populating with docker templates (#504)
1 parent 333c0f8 commit c23b24d

11 files changed

Lines changed: 893 additions & 0 deletions

File tree

templates/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Workflow Templates
2+
3+
#### Purpose
4+
5+
The intention of these templates is to provide a starting point for adding workflow support to repositories.<br/>
6+
They can be pulled together as necessary or have other steps added to meet the required need.
7+
8+

templates/docker/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Docker Workflow Templates
2+
3+
There are currently 2 types of templates:
4+
- Product Templates
5+
- Service Templates
6+
7+
### Product Template
8+
This can be used when docker images are released as a product to the public.<br/>
9+
See the [product folder's README](./product/README.md) for more information.
10+
11+
### Service Template
12+
This can be used when docker images are pushed as an internal service that supports either internal tools or the SAAS product.<br/>
13+
See the [service folder's README](./service/README.md) for more information.

templates/docker/product/README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Docker Workflow Templates for Product Images
2+
3+
These workflow templates can be copied and modified as necessary to support building, releasing, and publishing docker images.
4+
5+
## General Flow
6+
1. Build and Push
7+
2. Release
8+
3. Publish
9+
10+
## Templates
11+
12+
### Build and Push
13+
There are currently 2 versions of this template:
14+
- `build_push_acr.yml`
15+
- `build_push_ghcr.yml`
16+
17+
These can be combined if necessary for pushing to both ACR and GHCR.
18+
19+
Purpose: These build the docker image and push it out to registries if tags are set to be pushed (See below)
20+
21+
Tags that are pushed:
22+
- On push to main: `dev`
23+
- On PR: `pr-#`
24+
25+
---
26+
27+
### Release
28+
The `release.yml` workflow handles release both ACR and GHCR.
29+
It can be modified to adjust to only doing one by removing the respective job.
30+
31+
This will do 2 things:
32+
1. Create a GitHub Release
33+
2. Publish the `dev` tag as the release version tag in ACR and GHCR
34+
35+
Tags that are pushed:
36+
- Release version tag
37+
38+
---
39+
40+
### Publish
41+
The `publish.yml` workflow handles publishing both ACR and GHCR.
42+
It can be modified to adjust to only doing one by removing the respective job
43+
44+
This will copy the tag corresponding to the latest release to the `latest` tag
45+
46+
Tags that are pushed:
47+
- `latest`
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
name: Build
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- "main"
8+
workflow_dispatch:
9+
10+
permissions: {}
11+
12+
env:
13+
_AZURE_REGISTRY: bitwardenprod.azurecr.io
14+
_IMAGE_NAME: TEMPLATE_IMAGE_NAME # UPDATE: TEMPLATE VALUE TO UPDATE WHEN COPIED
15+
16+
jobs:
17+
build:
18+
name: Build
19+
runs-on: ubuntu-24.04
20+
permissions:
21+
contents: read
22+
security-events: write
23+
packages: write
24+
id-token: write
25+
26+
steps:
27+
- name: Check if image should be published
28+
env:
29+
PUBLISH_BRANCHES: "main"
30+
PUBLISH_TAGS: "false"
31+
PUBLISH_PR: "true"
32+
run: |
33+
BRANCH_REF=${GITHUB_REF#refs/heads/}
34+
IFS="," read -a publish_branches <<< "$PUBLISH_BRANCHES"
35+
36+
if [[ "${PUBLISH_TAGS}" == "true" && "${GITHUB_REF}" == refs/tags/* ]]; then
37+
echo "push_image=true" >> "$GITHUB_ENV"
38+
elif [[ "${publish_branches[*]}" =~ "${BRANCH_REF}" ]]; then
39+
echo "push_image=true" >> "$GITHUB_ENV"
40+
else
41+
echo "push_image=false" >> "$GITHUB_ENV"
42+
fi
43+
44+
- name: Check out repo
45+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
46+
with:
47+
persist-credentials: false
48+
49+
########## Set up Docker ##########
50+
- name: Set up QEMU emulators
51+
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
52+
53+
- name: Set up Docker Buildx
54+
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
55+
56+
########## Login to Docker registries ##########
57+
- name: Log in to Azure
58+
uses: bitwarden/gh-actions/azure-login@main
59+
with:
60+
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
61+
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
62+
client_id: ${{ secrets.AZURE_CLIENT_ID }}
63+
64+
- name: Login to Azure ACR
65+
run: az acr login -n "${_AZURE_REGISTRY%%.*}"
66+
67+
########## Generate image tag and build Docker image ##########
68+
- name: Generate Docker image tag
69+
id: tag
70+
env:
71+
EVENT_TYPE: ${{ contains(github.event_name, 'pull_request') && 'pull_request' || '' }}
72+
run: |
73+
if [[ "$EVENT_TYPE" == "pull_request" ]]; then
74+
IMAGE_TAG="pr-${{ github.event.pull_request.number }}"
75+
else
76+
IMAGE_TAG=$(echo "${GITHUB_REF:11}" | sed "s#/#-#g") # slash safe branch name
77+
if [[ "$IMAGE_TAG" == "main" ]]; then
78+
IMAGE_TAG=dev
79+
fi
80+
fi
81+
echo "image_tag=$IMAGE_TAG" >> "$GITHUB_OUTPUT"
82+
83+
- name: Generate image tag(s)
84+
id: image-tags
85+
env:
86+
IMAGE_TAG: ${{ steps.tag.outputs.image_tag }}
87+
SHA: ${{ github.sha }}
88+
run: |
89+
FULL_IMAGE_NAME="${_AZURE_REGISTRY}/${_IMAGE_NAME}"
90+
TAGS="${FULL_IMAGE_NAME}:${IMAGE_TAG}"
91+
echo "primary_tag=$TAGS" >> "$GITHUB_OUTPUT"
92+
if [[ "$IMAGE_TAG" == "dev" ]]; then
93+
SHORT_SHA="$(git rev-parse --short "${SHA}")"
94+
TAGS="$TAGS,${FULL_IMAGE_NAME}:${IMAGE_TAG}-${SHORT_SHA}"
95+
fi
96+
echo "tags=$TAGS" >> "$GITHUB_OUTPUT"
97+
98+
########## Build Docker image ##########
99+
- name: Build Docker image
100+
id: build-docker
101+
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
102+
with:
103+
context: .
104+
file: Dockerfile
105+
platforms: linux/amd64
106+
push: ${{ env.push_image == 'true' }}
107+
tags: ${{ steps.image-tags.outputs.tags }}
108+
env:
109+
DOCKER_BUILD_RECORD_UPLOAD: false
110+
111+
- name: Install Cosign
112+
if: env.push_image == 'true'
113+
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
114+
115+
- name: Sign image with Cosign
116+
if: env.push_image == 'true'
117+
env:
118+
DIGEST: ${{ steps.build-docker.outputs.digest }}
119+
TAGS: ${{ steps.image-tags.outputs.tags }}
120+
run: |
121+
IFS=',' read -r -a tags_array <<< "${TAGS}"
122+
images=()
123+
for tag in "${tags_array[@]}"; do
124+
images+=("${tag}@${DIGEST}")
125+
done
126+
cosign sign --yes ${images[@]} # Do not quote the array to expand properly
127+
128+
- name: Scan Docker image
129+
id: container-scan
130+
uses: anchore/scan-action@568b89d27fc18c60e56937bff480c91c772cd993 # v7.1.0
131+
with:
132+
image: ${{ steps.image-tags.outputs.primary_tag }}
133+
fail-build: false
134+
output-format: sarif
135+
136+
- name: Upload Grype results to GitHub
137+
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
138+
uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
139+
with:
140+
sarif_file: ${{ steps.container-scan.outputs.sarif }}
141+
sha: ${{ contains(github.event_name, 'pull_request') && github.event.pull_request.head.sha || github.sha }}
142+
ref: ${{ contains(github.event_name, 'pull_request') && format('refs/pull/{0}/head', github.event.pull_request.number) || github.ref }}
143+
144+
- name: Log out of Docker
145+
run: |
146+
docker logout "$_AZURE_REGISTRY"
147+
148+
- name: Log out from Azure
149+
uses: bitwarden/gh-actions/azure-logout@main
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
name: Build
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- "main"
8+
workflow_dispatch:
9+
10+
permissions: {}
11+
12+
env:
13+
_IMAGE_NAME: ghcr.io/bitwarden/TEMPLATE_IMAGE_NAME # TEMPLATE VALUE TO UPDATE WHEN COPIED
14+
15+
jobs:
16+
build:
17+
name: Build
18+
runs-on: ubuntu-24.04
19+
permissions:
20+
contents: read
21+
security-events: write
22+
packages: write
23+
id-token: write
24+
25+
steps:
26+
- name: Check if image should be published
27+
env:
28+
PUBLISH_BRANCHES: "main"
29+
PUBLISH_TAGS: "false"
30+
PUBLISH_PR: "true"
31+
run: |
32+
BRANCH_REF=${GITHUB_REF#refs/heads/}
33+
IFS="," read -a publish_branches <<< "$PUBLISH_BRANCHES"
34+
35+
if [[ "${PUBLISH_TAGS}" == "true" && "${GITHUB_REF}" == refs/tags/* ]]; then
36+
echo "push_image=true" >> "$GITHUB_ENV"
37+
elif [[ "${publish_branches[*]}" =~ "${BRANCH_REF}" ]]; then
38+
echo "push_image=true" >> "$GITHUB_ENV"
39+
else
40+
echo "push_image=false" >> "$GITHUB_ENV"
41+
fi
42+
43+
- name: Check out repo
44+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
45+
with:
46+
persist-credentials: false
47+
48+
########## Set up Docker ##########
49+
- name: Set up QEMU emulators
50+
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
51+
52+
- name: Set up Docker Buildx
53+
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
54+
55+
########## Login to Docker registries ##########
56+
- name: Log in to GitHub Container Registry
57+
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
58+
with:
59+
registry: ghcr.io
60+
username: ${{ github.actor }}
61+
password: ${{ secrets.GITHUB_TOKEN }}
62+
63+
########## Generate image tag and build Docker image ##########
64+
- name: Generate Docker image tag
65+
id: tag
66+
env:
67+
EVENT_TYPE: ${{ contains(github.event_name, 'pull_request') && 'pull_request' || '' }}
68+
run: |
69+
if [[ "$EVENT_TYPE" == "pull_request" ]]; then
70+
IMAGE_TAG="pr-${{ github.event.pull_request.number }}"
71+
else
72+
IMAGE_TAG=$(echo "${GITHUB_REF:11}" | sed "s#/#-#g") # slash safe branch name
73+
if [[ "$IMAGE_TAG" == "main" ]]; then
74+
IMAGE_TAG=dev
75+
fi
76+
fi
77+
echo "image_tag=$IMAGE_TAG" >> "$GITHUB_OUTPUT"
78+
79+
- name: Generate image tag(s)
80+
id: image-tags
81+
env:
82+
IMAGE_TAG: ${{ steps.tag.outputs.image_tag }}
83+
SHA: ${{ github.sha }}
84+
run: |
85+
TAGS="${_IMAGE_NAME}:${IMAGE_TAG}"
86+
echo "primary_tag=$TAGS" >> "$GITHUB_OUTPUT"
87+
if [[ "$IMAGE_TAG" == "dev" ]]; then
88+
SHORT_SHA="$(git rev-parse --short "${SHA}")"
89+
TAGS="$TAGS,${_IMAGE_NAME}:${IMAGE_TAG}-${SHORT_SHA}"
90+
fi
91+
echo "tags=$TAGS" >> "$GITHUB_OUTPUT"
92+
93+
########## Build Docker image ##########
94+
- name: Build Docker image
95+
id: build-docker
96+
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
97+
with:
98+
context: .
99+
file: Dockerfile
100+
platforms: linux/amd64
101+
push: ${{ env.push_image == 'true' }}
102+
tags: ${{ steps.image-tags.outputs.tags }}
103+
env:
104+
DOCKER_BUILD_RECORD_UPLOAD: false
105+
106+
- name: Install Cosign
107+
if: env.push_image == 'true'
108+
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
109+
110+
- name: Sign image with Cosign
111+
if: env.push_image == 'true'
112+
env:
113+
DIGEST: ${{ steps.build-docker.outputs.digest }}
114+
TAGS: ${{ steps.image-tags.outputs.tags }}
115+
run: |
116+
IFS=',' read -r -a tags_array <<< "${TAGS}"
117+
images=()
118+
for tag in "${tags_array[@]}"; do
119+
images+=("${tag}@${DIGEST}")
120+
done
121+
cosign sign --yes ${images[@]} # Do not quote the array to expand properly
122+
123+
- name: Scan Docker image
124+
id: container-scan
125+
uses: anchore/scan-action@568b89d27fc18c60e56937bff480c91c772cd993 # v7.1.0
126+
with:
127+
image: ${{ steps.image-tags.outputs.primary_tag }}
128+
fail-build: false
129+
output-format: sarif
130+
131+
- name: Upload Grype results to GitHub
132+
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
133+
uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
134+
with:
135+
sarif_file: ${{ steps.container-scan.outputs.sarif }}
136+
sha: ${{ contains(github.event_name, 'pull_request') && github.event.pull_request.head.sha || github.sha }}
137+
ref: ${{ contains(github.event_name, 'pull_request') && format('refs/pull/{0}/head', github.event.pull_request.number) || github.ref }}
138+
139+
- name: Log out of Docker
140+
run: |
141+
docker logout ghcr.io

0 commit comments

Comments
 (0)