Skip to content

Commit c0e8259

Browse files
TimHessbart-vmware
andauthored
Refactor image building to use committed source and a dedicated release workflow (#62)
Move image update process to a new script, update manual and CI workflows accordingly and with additional improvements: - Use a shared workflow for building images - Use latest major versions of all actions - Commit image source code - Add smoke tests for all images - Add new workflow for production releases. (Workflows on main now produce "edge" tag) - Move initializr-related logic from build.ps1 to update-project.ps1 - Pin dependencies - Bump Spring Boot and inner server package versions - Expand README.md, trim AGENTS.md. Update both for these changes. - More consistent PowerShell formatting --------- Co-authored-by: Bart Koelman <104792814+bart-vmware@users.noreply.github.com>
1 parent be2b5c4 commit c0e8259

78 files changed

Lines changed: 3288 additions & 577 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,20 @@
11
# Patches are applied on files extracted from a downloaded zip file. All these files use LF line endings.
22
*.patch text eol=lf
3+
4+
# Spring Initializr generates source files with LF line endings (Linux server).
5+
# Explicit rules here prevent unexpected diffs when update-project.ps1 regenerates source on Windows,
6+
# where core.autocrlf would otherwise convert committed files to CRLF on checkout.
7+
**/source/**/*.java text eol=lf
8+
**/source/**/*.gradle text eol=lf
9+
**/source/**/*.properties text eol=lf
10+
**/source/**/*.md text eol=lf
11+
**/source/**/*.txt text eol=lf
12+
**/source/**/*.xml text eol=lf
13+
**/source/**/gradlew text eol=lf
14+
**/source/**/gradlew.bat text eol=crlf
15+
**/source/**/*.jar binary
16+
17+
# Customizations are appended/overlaid onto the generated (LF) source by update-project.ps1,
18+
# so keep them LF to avoid introducing CRLF when regenerating on Windows.
19+
**/customizations/build.gradle.append text eol=lf
20+
**/customizations/overlay/**/*.java text eol=lf

.github/workflows/build-image.yaml

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
name: Build Image
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
image:
7+
description: 'Image name (for example: config-server)'
8+
required: true
9+
type: string
10+
description:
11+
description: 'Human-readable image description for PR comments'
12+
required: true
13+
type: string
14+
15+
jobs:
16+
build-push:
17+
name: Build and push image
18+
runs-on: ubuntu-latest
19+
env:
20+
TAG: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || 'edge' }}
21+
REGISTRY: ${{ vars.DOCKER_REGISTRY }}
22+
23+
steps:
24+
- name: Git checkout
25+
uses: actions/checkout@v6
26+
with:
27+
persist-credentials: false
28+
29+
- name: Read image config
30+
id: config
31+
shell: bash
32+
run: echo "port=$(cat '${{ inputs.image }}/metadata/PORT' | tr -d '[:space:]')" >> $GITHUB_OUTPUT
33+
34+
- name: Set up JDK 25
35+
if: inputs.image != 'uaa-server'
36+
uses: actions/setup-java@v5
37+
with:
38+
distribution: temurin
39+
java-version: '25'
40+
cache: gradle
41+
42+
- name: Build image
43+
shell: pwsh
44+
run: ./build.ps1 -Name '${{ inputs.image }}' -Registry '${{ env.REGISTRY }}' -Tag '${{ env.TAG }}'
45+
46+
- name: Smoke test image
47+
shell: pwsh
48+
run: ./smoke-test.ps1 -Name '${{ inputs.image }}' -Registry '${{ env.REGISTRY }}' -Tag '${{ env.TAG }}'
49+
50+
- name: Login to container registry
51+
uses: docker/login-action@v4
52+
with:
53+
registry: ${{ env.REGISTRY }}
54+
username: ${{ secrets.DOCKER_USERNAME }}
55+
password: ${{ secrets.DOCKER_PASSWORD }}
56+
57+
- name: Push image
58+
run: docker push ${{ env.REGISTRY }}/${{ inputs.image }}:${{ env.TAG }}
59+
60+
- name: Post or update PR comment with image run instructions
61+
uses: actions/github-script@v9
62+
if: ${{ github.event_name == 'pull_request' }}
63+
with:
64+
script: |
65+
const marker = '<!-- IMAGE_INSTRUCTIONS_${{ inputs.image }} -->';
66+
const body = `${marker}
67+
To run the ${{ inputs.description }} image built for this pull request:
68+
\`\`\`bash
69+
docker run --rm -d --pull=always -p ${{ steps.config.outputs.port }}:${{ steps.config.outputs.port }} --name ${{ inputs.image }}-pr ${{ env.REGISTRY }}/${{ inputs.image }}:${{ env.TAG }}
70+
\`\`\``;
71+
72+
const { data: comments } = await github.rest.issues.listComments({
73+
owner: context.repo.owner,
74+
repo: context.repo.repo,
75+
issue_number: context.issue.number,
76+
per_page: 100,
77+
});
78+
79+
const existingComment = comments.find(comment =>
80+
comment.user.login === 'github-actions[bot]' && comment.body.startsWith(marker)
81+
);
82+
83+
if (existingComment) {
84+
await github.rest.issues.updateComment({
85+
owner: context.repo.owner,
86+
repo: context.repo.repo,
87+
comment_id: existingComment.id,
88+
body: body,
89+
});
90+
} else {
91+
await github.rest.issues.createComment({
92+
owner: context.repo.owner,
93+
repo: context.repo.repo,
94+
issue_number: context.issue.number,
95+
body: body,
96+
});
97+
}

.github/workflows/build_config_server.yaml

Lines changed: 13 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@ on:
44
pull_request:
55
paths:
66
- '.github/workflows/build_config_server.yaml'
7-
- 'config-server/metadata/*'
8-
- 'config-server/patches/*'
7+
- '.github/workflows/build-image.yaml'
8+
- 'config-server/**'
9+
- '!config-server/README.md'
910
- 'build.ps1'
1011
push:
1112
branches:
1213
- main
1314
paths:
1415
- '.github/workflows/build_config_server.yaml'
15-
- 'config-server/metadata/*'
16-
- 'config-server/patches/*'
16+
- '.github/workflows/build-image.yaml'
17+
- 'config-server/**'
18+
- '!config-server/README.md'
1719
- 'build.ps1'
1820

1921
concurrency:
@@ -22,70 +24,12 @@ concurrency:
2224

2325
permissions:
2426
contents: read
25-
pull-requests: 'write'
26-
27-
env:
28-
IMAGE_NAME: config-server
29-
REGISTRY: ${{ vars.DOCKER_REGISTRY }}
27+
pull-requests: write
3028

3129
jobs:
32-
build-push:
33-
name: Build and push image
34-
runs-on: ubuntu-latest
35-
steps:
36-
- uses: actions/checkout@v4
37-
38-
- name: Build Image
39-
run: ./build.ps1 -Name '${{ env.IMAGE_NAME }}' -Registry '${{ env.REGISTRY }}' -Tag '${{ env.TAG }}'
40-
shell: pwsh
41-
env:
42-
TAG: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || '' }}
43-
44-
- name: Login to container registry
45-
uses: docker/login-action@v3
46-
with:
47-
registry: ${{ vars.DOCKER_REGISTRY }}
48-
username: ${{ secrets.DOCKER_USERNAME }}
49-
password: ${{ secrets.DOCKER_PASSWORD }}
50-
51-
- name: Push image
52-
run: docker push --all-tags ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
53-
54-
- name: Post or update PR comment with image run instructions
55-
uses: actions/github-script@v7
56-
if: ${{ github.event_name == 'pull_request' }}
57-
with:
58-
script: |
59-
const marker = '<!-- IMAGE_INSTRUCTIONS_CONFIG_SERVER -->';
60-
const body = `${marker}
61-
To run the Spring Cloud Config Server image built for this pull request:
62-
\`\`\`bash
63-
docker run --rm -d --pull=always -p 8888:8888 --name config-pr steeltoe.azurecr.io/config-server:pr-${{ github.event.number }}
64-
\`\`\``;
65-
66-
const { data: comments } = await github.rest.issues.listComments({
67-
owner: context.repo.owner,
68-
repo: context.repo.repo,
69-
issue_number: context.issue.number,
70-
per_page: 100,
71-
});
72-
73-
const existingComment = comments.find(comment =>
74-
comment.user.login === 'github-actions[bot]' && comment.body.startsWith(marker)
75-
);
76-
77-
if (existingComment) {
78-
await github.rest.issues.updateComment({
79-
owner: context.repo.owner,
80-
repo: context.repo.repo,
81-
comment_id: existingComment.id,
82-
body: body,
83-
});
84-
} else {
85-
await github.rest.issues.createComment({
86-
owner: context.repo.owner,
87-
repo: context.repo.repo,
88-
issue_number: context.issue.number,
89-
body: body,
90-
});
91-
}
30+
build:
31+
uses: ./.github/workflows/build-image.yaml
32+
with:
33+
image: config-server
34+
description: Spring Cloud Config Server
35+
secrets: inherit

.github/workflows/build_eureka_server.yaml

Lines changed: 13 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@ on:
44
pull_request:
55
paths:
66
- '.github/workflows/build_eureka_server.yaml'
7-
- 'eureka-server/metadata/*'
8-
- 'eureka-server/patches/*'
7+
- '.github/workflows/build-image.yaml'
8+
- 'eureka-server/**'
9+
- '!eureka-server/README.md'
910
- 'build.ps1'
1011
push:
1112
branches:
1213
- main
1314
paths:
1415
- '.github/workflows/build_eureka_server.yaml'
15-
- 'eureka-server/metadata/*'
16-
- 'eureka-server/patches/*'
16+
- '.github/workflows/build-image.yaml'
17+
- 'eureka-server/**'
18+
- '!eureka-server/README.md'
1719
- 'build.ps1'
1820

1921
concurrency:
@@ -22,70 +24,12 @@ concurrency:
2224

2325
permissions:
2426
contents: read
25-
pull-requests: 'write'
26-
27-
env:
28-
IMAGE_NAME: eureka-server
29-
REGISTRY: ${{ vars.DOCKER_REGISTRY }}
27+
pull-requests: write
3028

3129
jobs:
32-
build-push:
33-
name: Build and push image
34-
runs-on: ubuntu-latest
35-
steps:
36-
- uses: actions/checkout@v4
37-
38-
- name: Build Image
39-
run: ./build.ps1 -Name '${{ env.IMAGE_NAME }}' -Registry '${{ env.REGISTRY }}' -Tag '${{ env.TAG }}'
40-
shell: pwsh
41-
env:
42-
TAG: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || '' }}
43-
44-
- name: Login to container registry
45-
uses: docker/login-action@v3
46-
with:
47-
registry: ${{ vars.DOCKER_REGISTRY }}
48-
username: ${{ secrets.DOCKER_USERNAME }}
49-
password: ${{ secrets.DOCKER_PASSWORD }}
50-
51-
- name: Push image
52-
run: docker push --all-tags ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
53-
54-
- name: Post or update PR comment with image run instructions
55-
uses: actions/github-script@v7
56-
if: ${{ github.event_name == 'pull_request' }}
57-
with:
58-
script: |
59-
const marker = '<!-- IMAGE_INSTRUCTIONS_EUREKA_SERVER -->';
60-
const body = `${marker}
61-
To run the Eureka server image built for this pull request:
62-
\`\`\`bash
63-
docker run --rm -d --pull=always -p 8761:8761 --name eureka-pr steeltoe.azurecr.io/eureka-server:pr-${{ github.event.number }}
64-
\`\`\``;
65-
66-
const { data: comments } = await github.rest.issues.listComments({
67-
owner: context.repo.owner,
68-
repo: context.repo.repo,
69-
issue_number: context.issue.number,
70-
per_page: 100,
71-
});
72-
73-
const existingComment = comments.find(comment =>
74-
comment.user.login === 'github-actions[bot]' && comment.body.startsWith(marker)
75-
);
76-
77-
if (existingComment) {
78-
await github.rest.issues.updateComment({
79-
owner: context.repo.owner,
80-
repo: context.repo.repo,
81-
comment_id: existingComment.id,
82-
body: body,
83-
});
84-
} else {
85-
await github.rest.issues.createComment({
86-
owner: context.repo.owner,
87-
repo: context.repo.repo,
88-
issue_number: context.issue.number,
89-
body: body,
90-
});
91-
}
30+
build:
31+
uses: ./.github/workflows/build-image.yaml
32+
with:
33+
image: eureka-server
34+
description: Spring Cloud Netflix Eureka Server
35+
secrets: inherit

0 commit comments

Comments
 (0)