Skip to content

Commit

Permalink
feat(workflows/docker-build-images): add strategy to defined runner r…
Browse files Browse the repository at this point in the history
…egarding platform type

Signed-off-by: Emilien Escalle <[email protected]>
  • Loading branch information
neilime committed Jan 24, 2025
1 parent 68a2e5b commit 82a64e2
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 27 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/__test-workflow-docker-build-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
"dockerfile": "./tests/application/Dockerfile",
"build-args": { "PROD_MODE": "true" },
"target": "prod",
"platforms": ["linux/amd64","linux/arm64","linux/arm/v7"]
"platforms": ["linux/amd64","linux/arm64","linux/arm/v7","darwin/amd64","windows/amd64"]
},
{
"name": "application-mono-arch",
Expand Down
16 changes: 15 additions & 1 deletion .github/workflows/docker-build-images.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ jobs:
# Default: "${{ github.repository_owner }}"
oci-registry-username: ""

# Images to build parameters.
# Images to build parameters. Json array of objects.
# Example: [{
# "name": "application",
# "dockerfile": "./docker/application/Dockerfile",
Expand Down Expand Up @@ -117,6 +117,20 @@ jobs:
| **<code>target</code>** | Sets the target stage to build. See [Docker build-image action](../../actions/docker/build-image/README.md) | | **true** |
| **<code>platforms</code>** | List of platforms to build for. It is used as `platform` in [Docker build-image action](../../actions/docker/build-image/README.md). Can be a string (Example: `linux/amd64`) or an object (Example: `{"name": "darwin/amd64","runs-on": "macos-latest"}`) | | **true** |

#### Platforms entry parameters

| **Parameter** | **Description** | **Default** | **Required** |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------- | ----------- | ------------ |
| **<code>name</code>** | Platform name. Example: `linux/amd64` | | **true** |
| **<code>runs-on</code>** | Json array of runner(s) to use. See <https://docs.github.com/en/actions/using-jobs/choosing-the-runner-for-a-job> | | **false** |

##### Default `runs-on` strategy

If a platform entry omits the <code>runs-on</code> field, the following default strategy applies:

- When the main <code>docker-build-images</code> job uses a standard hosted runner, that runner is automatically matched to each platform.
- If the main <code>docker-build-images</code> job uses a custom or self-hosted runner, all platforms use the same runner.

<!-- start outputs -->

## Outputs
Expand Down
64 changes: 54 additions & 10 deletions .github/workflows/docker-build-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ on: # yamllint disable-line rule:truthy
required: false
images:
description: |
Images to build parameters.
Images to build parameters. Json array of objects.
Example: [
{
"name": "application",
Expand Down Expand Up @@ -99,8 +99,8 @@ permissions:
jobs:
prepare-variables:
outputs:
images: ${{ steps.validate-inputs.outputs.images }}
artifact-name: ${{ steps.define-artifact-name.outputs.artifact-name }}
images: ${{ steps.define-images-by-platform.outputs.images }}
runs-on: ${{ fromJson(inputs.runs-on) }}
steps:
- id: validate-inputs
Expand Down Expand Up @@ -138,7 +138,6 @@ jobs:
// jscpd:ignore-end
// Check each item
const imagesByPlatform = [];
for (const key in images) {
const image = images[key];
if (typeof image !== 'object') {
Expand Down Expand Up @@ -172,24 +171,69 @@ jobs:
if (!image['repository']) {
image['repository'] = `${{ github.repository }}`;
}
}
core.setOutput('images', JSON.stringify(images));
- id: define-images-by-platform
uses: actions/[email protected]
with:
script: |
const imagesInput = JSON.parse(`${{ steps.validate-inputs.outputs.images }}`);
const runsOnInput = `${{ inputs.runs-on }}`;
const isDefaultRunsOn = runsOnInput === '["ubuntu-latest"]';
// See https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories
const standardHostedRunnerByPlatform = [
{ runner: "ubuntu-24.04-arm", platformPattern: /^linux\/arm/ }, // FIXME: should use latest when available
{ runner: "macos-latest", platformPattern: /^darwin\// },
{ runner: "windows-latest", platformPattern: /^windows\// }
];
function getPlatformRunsOn(platform) {
if (platform.hasOwnProperty('runs-on')) {
return platform['runs-on'];
}
if (!isDefaultRunsOn) {
return runsOnInput;
}
for (const { runner, platformPattern } of standardHostedRunnerByPlatform) {
if (platformPattern.test(platform.name)) {
return [runner];
}
}
return runsOnInput;
}
// Check each item
const imagesByPlatform = [];
for (const key in images) {
const image = images[key];
// Add image for each platform
const platforms = image['platforms'];
for (const platform of platforms) {
let platformName = platform;
let platformRunsOn = runsOn;
let platformName;
let platformRunsOn;
// Platform can be a string or an object
if (typeof platform === 'object') {
if (!platform.hasOwnProperty('name')) {
throw new Error(`"images[${key}].platforms[${platform}].name" input is missing`);
}
platformName = platform['name'];
if (platform.hasOwnProperty('runs-on')) {
platformRunsOn = platform['runs-on'];
}
} else if (typeof platform !== 'string') {
platformRunsOn = getPlatformRunsOn(platform);
} else if (typeof platform === 'string') {
platformName = platform;
platformRunsOn = getPlatformRunsOn({ name: platform });
} else {
throw new Error(`"images[${key}].platforms[${platform}]" input is not a string or an object`);
}
Expand Down
14 changes: 6 additions & 8 deletions tests/charts/application/templates/service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "test-application.fullname" . }}
namespace: {{ .Values.namespace }}
labels:
{{- include "test-application.labels" . | nindent 4 }}
name: { { include "test-application.fullname" . } }
namespace: { { .Values.namespace } }
labels: { { - include "test-application.labels" . | nindent 4 } }
spec:
type: {{ .Values.service.type }}
type: { { .Values.service.type } }
ports:
- port: {{ .Values.service.port }}
- port: { { .Values.service.port } }
targetPort: http
protocol: TCP
name: http
selector:
{{- include "test-application.selectorLabels" . | nindent 4 }}
selector: { { - include "test-application.selectorLabels" . | nindent 4 } }
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "app.fullname" . }}
namespace: {{ .Values.namespace }}
labels: {{- include "app.labels" . | nindent 4 }}
name: { { include "app.fullname" . } }
namespace: { { .Values.namespace } }
labels: { { - include "app.labels" . | nindent 4 } }
spec:
type: {{ .Values.service.type }}
type: { { .Values.service.type } }
ports:
- port: {{ .Values.service.port }}
- port: { { .Values.service.port } }
targetPort: http
protocol: TCP
name: http
selector: {{- include "app.selectorLabels" . | nindent 4 }}
selector: { { - include "app.selectorLabels" . | nindent 4 } }
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ ingress:
hosts:
- host: chart-example.local
paths:
- path: ''
- path: ""
pathType: ImplementationSpecific
tls: []

0 comments on commit 82a64e2

Please sign in to comment.