99 pull_request :
1010 branches :
1111 - " master"
12+ workflow_dispatch :
13+ inputs :
14+ ref :
15+ description : " Tag to build (e.g. v0.1.0)"
16+ required : true
1217
1318env :
1419 IMAGE_NAME : ${{ github.repository }}
1520 REGISTRY : ghcr.io
1621
1722jobs :
18- build :
19- name : Build Docker image
20- runs-on : ubuntu-latest
23+ build-riverui :
24+ name : " Build Docker image: riverui "
25+ runs-on : ${{ matrix.runner }}
2126 strategy :
2227 matrix :
23- docker_platform :
24- - linux/amd64
25- - linux/arm64
26- - linux/arm64/v8
28+ include :
29+ - docker_platform : linux/amd64
30+ runner : ubuntu-latest
31+ - docker_platform : linux/arm64
32+ runner : ubuntu-24.04-arm64
2733 outputs :
2834 tags : ${{ steps.meta.outputs.tags }}
2935 labels : ${{ steps.meta.outputs.labels }}
@@ -36,15 +42,14 @@ jobs:
3642 steps :
3743 - name : Checkout
3844 uses : actions/checkout@v4
45+ with :
46+ ref : ${{ inputs.ref || github.ref }}
3947
4048 - name : Prepare
4149 run : |
4250 platform=${{ matrix.docker_platform }}
4351 echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
4452
45- - name : Set up QEMU
46- uses : docker/setup-qemu-action@v3
47-
4853 - name : Set up Docker Buildx
4954 uses : docker/setup-buildx-action@v3
5055
5964 id : meta
6065 uses : docker/metadata-action@v5
6166 with :
62- images : ghcr.io/${{ github.repository }}
67+ images : ghcr.io/${{ env.IMAGE_NAME }}
6368 labels : |
6469 org.opencontainers.image.source=https://github.com/riverqueue/riverui
6570 org.opencontainers.image.description="River UI is a web-based user interface for River, a fast and reliable background job system."
6974 type=ref,event=pr
7075 type=semver,pattern={{version}}
7176 type=semver,pattern={{major}}.{{minor}}
77+ type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }}
7278
7379 - name : Build and push to GitHub Container Registry
7480 id : build
@@ -98,63 +104,150 @@ jobs:
98104 - name : Upload digest
99105 uses : actions/upload-artifact@v4
100106 with :
101- name : digests-${{ env.PLATFORM_PAIR }}
107+ name : digests-oss- ${{ env.PLATFORM_PAIR }}
102108 path : /tmp/digests/*
103109 if-no-files-found : error
104110 retention-days : 1
105111
106- merge :
107- name : Merge and publish image manifests
112+ build-riverproui :
113+ name : " Build Docker image: riverproui "
108114 runs-on : ubuntu-latest
109- needs :
110- - build
115+ # TODO: disabled for testing
116+ # if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'
111117 permissions :
118+ attestations : write
112119 contents : read
113120 id-token : write
114- packages : write
115121
116122 steps :
117123 - name : Checkout
118124 uses : actions/checkout@v4
119-
120- - name : Download digests
121- uses : actions/download-artifact@v4
122125 with :
123- path : /tmp/digests
124- pattern : digests-*
125- merge-multiple : true
126+ ref : ${{ inputs.ref || github.ref }}
127+
128+ - name : Set TAG
129+ run : echo "TAG=${{ inputs.ref || github.ref_name }}" >> $GITHUB_ENV
130+
131+ - name : Validate TAG
132+ run : |
133+ if [[ ! "$TAG" == v* ]]; then
134+ echo "Tag must start with 'v'"
135+ exit 1
136+ fi
137+
138+ - name : Set up QEMU
139+ uses : docker/setup-qemu-action@v3
126140
127141 - name : Set up Docker Buildx
128142 uses : docker/setup-buildx-action@v3
129143
130- - name : Login to GitHub Container Registry
131- uses : docker/login-action@v3
144+ - name : Docker meta for Pro
145+ id : meta-pro
146+ uses : docker/metadata-action@v5
132147 with :
133- registry : ${{ env.REGISTRY }}
134- username : ${{ github.actor }}
135- password : ${{ secrets.GITHUB_TOKEN }}
148+ images : riverqueue.com/riverproui
149+ labels : |
150+ org.opencontainers.image.source=https://github.com/riverqueue/riverui
151+ org.opencontainers.image.description="River UI Pro is a web-based user interface for River, with pro features."
152+ org.opencontainers.image.licenses=MPL-2.0
153+ tags : |
154+ type=semver,pattern={{version}}
155+ type=semver,pattern={{major}}.{{minor}}
156+ type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }}
136157
137- - name : Docker meta
138- id : meta
158+ - name : Build and export to OCI
159+ uses : docker/build-push-action@v6
160+ with :
161+ context : .
162+ file : Dockerfile.pro
163+ platforms : linux/amd64,linux/arm64
164+ provenance : true
165+ push : false
166+ tags : ${{ steps.meta-pro.outputs.tags }}
167+ labels : ${{ steps.meta-pro.outputs.labels }}
168+ outputs : type=oci,dest=/tmp/oci
169+
170+ - name : Upload OCI artifact
171+ uses : actions/upload-artifact@v4
172+ with :
173+ name : pro-oci
174+ path : /tmp/oci
175+ retention-days : 1
176+
177+ publish-riverproui :
178+ name : " Publish Docker image: riverproui"
179+ runs-on : ubuntu-latest
180+ needs :
181+ - build-riverproui
182+ # TODO: disabled for testing
183+ # if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'
184+
185+ steps :
186+ - name : Checkout
187+ uses : actions/checkout@v4
188+ with :
189+ ref : ${{ inputs.ref || github.ref }}
190+
191+ - name : Download OCI artifact
192+ uses : actions/download-artifact@v4
193+ with :
194+ name : pro-oci
195+ path : /tmp/oci
196+
197+ - name : Install jq
198+ run : sudo apt-get update && sudo apt-get install -y jq
199+
200+ - name : Install AWS CLI
201+ uses : unfor19/install-aws-cli-action@v1
202+ with :
203+ version : 2
204+ verbose : false
205+ arch : amd64
206+
207+ - name : Configure AWS CLI
208+ run : |
209+ aws configure set aws_access_key_id ${{ secrets.R2_ACCESS_KEY_ID }}
210+ aws configure set aws_secret_access_key ${{ secrets.R2_SECRET_ACCESS_KEY }}
211+ aws configure set default.region auto
212+
213+ - name : Docker meta for Pro
214+ id : meta-pro
139215 uses : docker/metadata-action@v5
140216 with :
141- images : ghcr.io/${{ env.IMAGE_NAME }}
217+ images : riverqueue.com/riverproui
142218 labels : |
143219 org.opencontainers.image.source=https://github.com/riverqueue/riverui
144- org.opencontainers.image.description="River UI is a web-based user interface for River, a fast and reliable background job system."
220+ org.opencontainers.image.description="River UI Pro is a web-based user interface for River, a fast and reliable background job system, with pro features enabled ."
145221 org.opencontainers.image.licenses=MPL-2.0
146222 tags : |
147- type=ref,event=branch
148- type=ref,event=pr
149223 type=semver,pattern={{version}}
150224 type=semver,pattern={{major}}.{{minor}}
225+ type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }}
151226
152- - name : Create manifest list and push
153- working-directory : /tmp/digests
227+ - name : Sync blobs to R2
228+ env :
229+ DOCKER_RELEASE_STORAGE_BUCKET : ${{ vars.DOCKER_RELEASE_STORAGE_BUCKET }}
230+ REPO_NAME : riverqueue.com/riverproui
231+ ENDPOINT_URL : ${{ secrets.R2_ENDPOINT_URL }}
154232 run : |
155- docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
156- $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *)
233+ aws s3 cp /tmp/oci/blobs/sha256/ s3://$DOCKER_RELEASE_STORAGE_BUCKET/$REPO_NAME/blobs/sha256/ --recursive --endpoint-url $ENDPOINT_URL
157234
158- - name : Inspect image
235+ - name : Upload manifest by digest
236+ env :
237+ DOCKER_RELEASE_STORAGE_BUCKET : ${{ vars.DOCKER_RELEASE_STORAGE_BUCKET }}
238+ REPO_NAME : riverqueue.com/riverproui
239+ ENDPOINT_URL : ${{ secrets.R2_ENDPOINT_URL }}
240+ run : |
241+ MANIFEST_DIGEST=$(sha256sum /tmp/oci/index.json | awk '{print $1}')
242+ aws s3 cp /tmp/oci/index.json s3://$DOCKER_RELEASE_STORAGE_BUCKET/$REPO_NAME/manifests/sha256:$MANIFEST_DIGEST --content-type "application/vnd.docker.distribution.manifest.list.v2+json" --endpoint-url $ENDPOINT_URL
243+
244+ - name : Upload tagged manifests
245+ env :
246+ DOCKER_RELEASE_STORAGE_BUCKET : ${{ vars.DOCKER_RELEASE_STORAGE_BUCKET }}
247+ REPO_NAME : riverqueue.com/riverproui
248+ ENDPOINT_URL : ${{ secrets.R2_ENDPOINT_URL }}
159249 run : |
160- docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
250+ TAGS=$(echo '${{ steps.meta-pro.outputs.json }}' | jq -r '.tags[] | split("/")[-1]')
251+ for TAG in $TAGS; do
252+ aws s3 cp /tmp/oci/index.json s3://$DOCKER_RELEASE_STORAGE_BUCKET/$REPO_NAME/manifests/$TAG --content-type "application/vnd.docker.distribution.manifest.list.v2+json" --endpoint-url $ENDPOINT_URL
253+ done
0 commit comments