-
Notifications
You must be signed in to change notification settings - Fork 12
194 lines (186 loc) · 8.21 KB
/
build-test-publish.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
name: Build, Test, Publish
on:
pull_request:
push:
branches: ["main"]
schedule:
- cron: "0 0 * * 1-5"
workflow_dispatch:
permissions:
contents: read
defaults:
run:
# Setting an explicit bash shell ensures GitHub Actions enables pipefail mode too, rather
# than only error on exit. This is important for UX since this workflow uses pipes. See:
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell
shell: bash
jobs:
create:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
builder: ["buildpacks-20", "builder-classic-22", "builder-20", "builder-22", "salesforce-functions"]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Pack CLI
uses: buildpacks/github-actions/[email protected]
- name: Create builder image
run: pack builder create ${{ matrix.builder }} --config ${{ matrix.builder }}/builder.toml --pull-policy always
# We export the run image too (and not just the generated builder image), since it adds virtually
# no size to the archive (since the layers are mostly duplicates), and it ends up being quicker
# than docker pulling the run image in the jobs that perform the pack build.
# We manually compress the archive rather than relying upon actions/cache's compression, since
# it ends up being faster both in this job and also later when the images are consumed.
- name: Export Docker images from the Docker daemon
# Using sed rather than yq until this yq bug is fixed:
# https://github.com/mikefarah/yq/issues/1758
run: |
RUN_IMAGE_TAG=$(sed --quiet --regexp-extended --expression 's/run-image\s*=\s*"(.+)"/\1/p' ${{ matrix.builder }}/builder.toml)
docker save ${{ matrix.builder }} ${RUN_IMAGE_TAG} | zstd -T0 --long=31 -o images.tar.zst
# We use a cache here rather than artifacts because it's 4x faster and we
# don't need the builder archive outside of this workflow run anyway.
- name: Save Docker images to the cache
uses: actions/cache/save@v3
with:
key: ${{ github.run_id}}-${{ matrix.builder }}
path: images.tar.zst
test-guides:
runs-on: ubuntu-22.04
needs: create
strategy:
fail-fast: false
matrix:
builder: ["buildpacks-20", "builder-classic-22", "builder-20", "builder-22"]
language: ["go", "gradle", "java", "node-js", "php", "python", "ruby", "scala"]
include:
- builder: builder-classic-22
language: clojure
steps:
- name: Checkout getting started guide
uses: actions/checkout@v4
with:
ref: main
repository: heroku/${{ matrix.language }}-getting-started.git
- name: Install Pack CLI
uses: buildpacks/github-actions/[email protected]
- name: Restore Docker images from the cache
uses: actions/cache/restore@v3
with:
fail-on-cache-miss: true
key: ${{ github.run_id}}-${{ matrix.builder }}
path: images.tar.zst
env:
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1
- name: Load Docker images into the Docker daemon
run: zstd -dc --long=31 images.tar.zst | docker load
- name: Build getting started guide image
run: pack build getting-started --builder ${{ matrix.builder }} --trust-builder --pull-policy never
- name: Start getting started guide image
# The `DYNO` env var is set to more accurately reflect the Heroku environment, since some of the getting
# started guides use the presence of `DYNO` to determine whether to enable production mode or not.
run: docker run --name getting-started --detach -p 8080:8080 --env PORT=8080 --env DYNO=web.1 getting-started
- name: Test getting started web server response
run: |
if curl -sSf --retry 10 --retry-delay 1 --retry-all-errors --connect-timeout 3 http://localhost:8080 -o response.txt; then
echo "Successful response from server"
else
echo "Server did not respond successfully"
docker logs getting-started
[[ -f response.txt ]] && cat response.txt
exit 1
fi
test-functions:
runs-on: ubuntu-22.04
needs: create
strategy:
fail-fast: false
matrix:
builder: ["salesforce-functions"]
language: ["java", "javascript", "typescript"]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Pack CLI
uses: buildpacks/github-actions/[email protected]
- name: Restore Docker images from the cache
uses: actions/cache/restore@v3
with:
fail-on-cache-miss: true
key: ${{ github.run_id}}-${{ matrix.builder }}
path: images.tar.zst
env:
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1
- name: Load Docker images into the Docker daemon
run: zstd -dc --long=31 images.tar.zst | docker load
- name: Build example function image
run: pack build example-function --path salesforce-functions/examples/${{ matrix.language }} --builder ${{ matrix.builder }} --trust-builder --pull-policy never
- name: Start example function image
run: docker run --name example-function --detach -p 8080:8080 --env PORT=8080 --env DYNO=web.1 example-function
- name: Test example function web server response
run: |
if curl -sSf --retry 10 --retry-delay 1 --retry-all-errors --connect-timeout 3 -X POST -H 'x-health-check: true' http://localhost:8080 -o response.txt; then
echo "Successful response from function"
else
echo "Function did not respond successfully"
docker logs example-function
[[ -f response.txt ]] && cat response.txt
exit 1
fi
publish:
runs-on: ubuntu-22.04
if: success() && github.ref == 'refs/heads/main'
needs: ["test-guides", "test-functions"]
strategy:
fail-fast: false
matrix:
include:
- builder: buildpacks-20
tag_public: heroku/buildpacks:20
- builder: builder-classic-22
tag_public: heroku/builder-classic:22
- builder: builder-20
tag_public: heroku/builder:20
- builder: builder-22
tag_public: heroku/builder:22
- builder: salesforce-functions
tag_private: heroku-22:builder-functions
steps:
- name: Restore Docker images from the cache
uses: actions/cache/restore@v3
with:
fail-on-cache-miss: true
key: ${{ github.run_id}}-${{ matrix.builder }}
path: images.tar.zst
env:
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1
- name: Load Docker images into the Docker daemon
run: zstd -dc --long=31 images.tar.zst | docker load
- name: Log into Docker Hub
if: matrix.tag_public != ''
run: echo '${{ secrets.DOCKER_HUB_TOKEN }}' | docker login -u '${{ secrets.DOCKER_HUB_USER }}' --password-stdin
- name: Log into internal registry
if: matrix.tag_private != ''
run: |
REGISTRY_TOKEN=$(
curl -sSf --retry 3 --retry-delay 1 --retry-all-errors --connect-timeout 3 \
-X POST -d '{"username":"${{ secrets.SERVICE_TOKEN_USER_NAME }}", "password":"${{ secrets.SERVICE_TOKEN_PASSWORD }}"}' \
'${{ secrets.SERVICE_TOKEN_ENDPOINT }}' \
| jq --exit-status -r '.raw_id_token'
)
echo "${REGISTRY_TOKEN}" | docker login '${{ secrets.REGISTRY_HOST }}' -u '${{ secrets.REGISTRY_USER }}' --password-stdin
- name: Tag builder and push to Docker Hub
if: matrix.tag_public != ''
run: |
PUBLIC_IMAGE_URI='${{ matrix.tag_public }}'
set -x
docker tag '${{ matrix.builder }}' "${PUBLIC_IMAGE_URI}"
docker push "${PUBLIC_IMAGE_URI}"
- name: Tag builder and push to internal registry
if: matrix.tag_private != ''
run: |
PRIVATE_IMAGE_URI='${{ secrets.REGISTRY_HOST }}/s/${{ secrets.SERVICE_TOKEN_USER_NAME }}/${{ matrix.tag_private }}'
set -x
docker tag '${{ matrix.builder }}' "${PRIVATE_IMAGE_URI}"
docker push "${PRIVATE_IMAGE_URI}"