mirror of
https://github.com/mattermost/mattermost.git
synced 2026-11-03 12:48:37 -06:00
Tag the build server image on its Node version (#38281)
* Tag the build server image on its Node version
mattermost-build-server was published as :${GO_VERSION}, but the image
bakes NODE_VERSION into PATH at build time. Since setup-buildenv skips
the build whenever `docker manifest inspect` finds that tag, bumping the
Dockerfile's Node changed nothing: CI kept pulling the existing image,
and the new Node only appeared once a master merge overwrote the tag in
place -- which also silently changes what release branches pinned to
that tag resolve to.
Tag on both instead, e.g. go1.26.7-node24.11.1. A Node bump now names a
tag nobody has published, so it gets built and published exactly once,
the same way a Go bump does. The "go" prefix keeps these distinct from
the bare Go versions published under the old scheme.
server/build/buildenv-tag.sh is the one place that composes the tag, and
it verifies both Dockerfiles agree on Node since one tag covers both
images. CI resolves it where it already resolved the Go version and
propagates BUILD_SERVER_TAG, so the buildenv actions just take a string.
That leaves nothing needing a threaded Go version except the
actions/setup-go in server-test-template, which reads server/.go-version
via go-version-file. Only two of that template's seven callers shard at
all, so the rest were passing a value nothing read.
Node also moves to 24.11.1 to match .nvmrc, which is what the webapp's
engines constraint has expected for a while.
The buildenv job in server-ci.yml is renamed from "go" to match
server-ci-weekly and server-ci-nightly-race, so its check name changes
from "Compute Go Version" to "Build Environment".
* Fail the step when buildenv-tag.sh fails
`echo BUILD_SERVER_TAG=$(./buildenv-tag.sh)` reports echo's exit status,
not the script's, so under `bash -e` a failing script left the step green
and wrote an empty value:
$ bash -e -c 'echo "TAG=$(false)"; echo continued'
TAG=
continued
That defeated the consistency check the script exists for: on drift it
exits 1, the step passed anyway, and setup-buildenv went on to inspect
`mattermost-build-server:` with no tag -- failing well away from the
cause. Capture into a variable first, which `bash -e` does catch.
Applies to all nine call sites, including the ones already quoted;
quoting doesn't help here.
* Rebuild the buildenv image when a version pin changes
buildenv-tag.sh reads server/.go-version and .nvmrc, so name them in the
paths that trigger a republish.
Redundant in practice -- the script requires the pins and the Dockerfiles
to agree, so a valid pin change always carries a Dockerfile change, which
already triggers this -- but it makes the dependency explicit and fails
here rather than in Server CI.
* Pass buildenv inputs via env, not expression interpolation
GitHub expands `${{ }}` into the script before bash runs it, so
`echo "BUILDENV_TAG=${{ inputs.build-server-tag }}"` executed whatever
the input contained. That was reachable: buildenv-tag.sh reads
ARG NODE_VERSION straight out of a Dockerfile, and a fork PR controls
that file, so `ARG NODE_VERSION=$(...)` would have landed in the tag and
then in this script.
Pass all three inputs through env instead, and reject a tag that isn't
usable as a docker tag anyway.
Also fixes the aggregate's error message, which still named the 'go' job
after it was renamed to 'buildenv'.
* Don't write a literal expression in a shell comment
GitHub parses ${{ ... }} anywhere in the template, including inside a
run: block's comment text, so an empty one failed the action manifest:
"An expression was expected".
* Drop the redundant tag validation
The env mapping is the fix: bash gets the input as a value, never as
script text, so there is nothing left to inject with. The regex only
restated what docker would reject anyway.
* Validate the tag before emitting it
* Pass buildenv values as step outputs, not GITHUB_ENV
This commit is contained in:
1 parent
24e436e7ae
commit
8f6d17d875
13 files changed
+202
-117
No files matched your search
@@ -1,13 +1,13 @@
|
||||
name: Load build environment
|
||||
description: >
|
||||
Loads build-server images uploaded by setup-buildenv into the local Docker
|
||||
daemon, and resolves the image name from the Go version. Use in jobs that
|
||||
run the container directly (test jobs). For jobs that only need a shell
|
||||
inside the container, use run-in-buildenv instead.
|
||||
daemon, and resolves the image name from the tag. Use in jobs that run the
|
||||
container directly (test jobs). For jobs that only need a shell inside the
|
||||
container, use run-in-buildenv instead.
|
||||
|
||||
inputs:
|
||||
go-version:
|
||||
description: "Go version used to construct the image tag (e.g. 1.26.3)."
|
||||
build-server-tag:
|
||||
description: "Build image tag, from server/build/buildenv-tag.sh (e.g. go1.26.3-node24.11.1)"
|
||||
required: true
|
||||
fips-enabled:
|
||||
description: "Set to 'true' to resolve the FIPS build image"
|
||||
@@ -16,7 +16,7 @@ inputs:
|
||||
|
||||
outputs:
|
||||
image:
|
||||
description: "Fully-qualified build image name (e.g. mattermost/mattermost-build-server:1.26.3)."
|
||||
description: "Fully-qualified build image name (e.g. mattermost/mattermost-build-server:go1.26.3-node24.11.1)."
|
||||
value: ${{ steps.resolve.outputs.image }}
|
||||
|
||||
runs:
|
||||
@@ -57,10 +57,10 @@ runs:
|
||||
shell: bash
|
||||
env:
|
||||
FIPS: ${{ inputs.fips-enabled }}
|
||||
GO_VERSION: ${{ inputs.go-version }}
|
||||
TAG: ${{ inputs.build-server-tag }}
|
||||
run: |
|
||||
if [[ "${FIPS}" == 'true' ]]; then
|
||||
echo "image=mattermost/mattermost-build-server-fips:${GO_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
echo "image=mattermost/mattermost-build-server-fips:${TAG}" >> "${GITHUB_OUTPUT}"
|
||||
else
|
||||
echo "image=mattermost/mattermost-build-server:${GO_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
echo "image=mattermost/mattermost-build-server:${TAG}" >> "${GITHUB_OUTPUT}"
|
||||
fi
|
||||
@@ -14,8 +14,8 @@ inputs:
|
||||
run:
|
||||
description: "Bash script to execute inside the container"
|
||||
required: true
|
||||
go-version:
|
||||
description: "Go version to use (e.g. 1.24.3). Defaults to the version in server/.go-version."
|
||||
build-server-tag:
|
||||
description: "Build image tag. Defaults to server/build/buildenv-tag.sh."
|
||||
required: false
|
||||
default: ""
|
||||
fips-enabled:
|
||||
@@ -30,20 +30,22 @@ inputs:
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Read Go version
|
||||
- name: Read build image tag
|
||||
id: tag
|
||||
shell: bash
|
||||
env:
|
||||
GO_VERSION_INPUT: ${{ inputs.go-version }}
|
||||
TAG_INPUT: ${{ inputs.build-server-tag }}
|
||||
run: |
|
||||
if [[ -n "${GO_VERSION_INPUT}" ]]; then
|
||||
echo "GO_VERSION=${GO_VERSION_INPUT}" >> "${GITHUB_ENV}"
|
||||
if [[ -n "${TAG_INPUT}" ]]; then
|
||||
tag="${TAG_INPUT}"
|
||||
else
|
||||
echo "GO_VERSION=$(cat server/.go-version)" >> "${GITHUB_ENV}"
|
||||
tag=$(./server/build/buildenv-tag.sh)
|
||||
fi
|
||||
echo "tag=${tag}" >> "${GITHUB_OUTPUT}"
|
||||
- uses: ./.github/actions/load-buildenv
|
||||
id: buildenv
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
build-server-tag: ${{ steps.tag.outputs.tag }}
|
||||
fips-enabled: ${{ inputs.fips-enabled }}
|
||||
- name: Run in buildenv
|
||||
shell: bash
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
name: Setup build environment
|
||||
description: >
|
||||
Builds the mattermost-build-server images if they don't yet exist on Docker
|
||||
Hub (e.g. during a Go version bump), and uploads them as artifacts for
|
||||
downstream jobs. Run once per workflow before any build or test jobs.
|
||||
Hub (e.g. during a Go or Node version bump), and uploads them as artifacts
|
||||
for downstream jobs. Run once per workflow before any build or test jobs.
|
||||
|
||||
inputs:
|
||||
go-version:
|
||||
description: "Go version (e.g. 1.26.3)"
|
||||
build-server-tag:
|
||||
description: "Build image tag, from server/build/buildenv-tag.sh (e.g. go1.26.3-node24.11.1)"
|
||||
required: true
|
||||
dockerfile:
|
||||
description: "Path to Dockerfile.buildenv (relative to workspace root)"
|
||||
@@ -21,44 +21,50 @@ runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Set constants
|
||||
id: constants
|
||||
shell: bash
|
||||
run: |
|
||||
echo "BUILDENV_IMAGE=mattermost/mattermost-build-server" >> "${GITHUB_ENV}"
|
||||
echo "BUILDENV_ARTIFACT=buildenv-image" >> "${GITHUB_ENV}"
|
||||
echo "BUILDENV_DOCKERFILE=${{ inputs.dockerfile }}" >> "${GITHUB_ENV}"
|
||||
echo "BUILDENV_FIPS_IMAGE=mattermost/mattermost-build-server-fips" >> "${GITHUB_ENV}"
|
||||
echo "BUILDENV_FIPS_ARTIFACT=buildenv-fips-image" >> "${GITHUB_ENV}"
|
||||
echo "BUILDENV_FIPS_DOCKERFILE=${{ inputs.dockerfile-fips }}" >> "${GITHUB_ENV}"
|
||||
echo "BUILDENV_TMPDIR=/tmp/buildenv-save" >> "${GITHUB_ENV}"
|
||||
{
|
||||
echo "image=mattermost/mattermost-build-server"
|
||||
echo "artifact=buildenv-image"
|
||||
echo "fips-image=mattermost/mattermost-build-server-fips"
|
||||
echo "fips-artifact=buildenv-fips-image"
|
||||
echo "tmpdir=/tmp/buildenv-save"
|
||||
} >> "${GITHUB_OUTPUT}"
|
||||
# ── Regular ────────────────────────────────────────────────────────
|
||||
- name: Resolve regular image
|
||||
id: resolve
|
||||
shell: bash
|
||||
env:
|
||||
GO_VERSION: ${{ inputs.go-version }}
|
||||
BUILDENV_IMAGE: ${{ steps.constants.outputs.image }}
|
||||
BUILDENV_TAG: ${{ inputs.build-server-tag }}
|
||||
run: |
|
||||
docker manifest inspect "${BUILDENV_IMAGE}:${GO_VERSION}" > /dev/null 2>&1 || \
|
||||
docker manifest inspect "${BUILDENV_IMAGE}:${BUILDENV_TAG}" > /dev/null 2>&1 || \
|
||||
echo "needs-build=true" >> "${GITHUB_OUTPUT}"
|
||||
- name: Build regular image
|
||||
if: ${{ steps.resolve.outputs.needs-build == 'true' }}
|
||||
shell: bash
|
||||
env:
|
||||
GO_VERSION: ${{ inputs.go-version }}
|
||||
run: docker build -t "${BUILDENV_IMAGE}:${GO_VERSION}" - < "${BUILDENV_DOCKERFILE}"
|
||||
BUILDENV_IMAGE: ${{ steps.constants.outputs.image }}
|
||||
BUILDENV_TAG: ${{ inputs.build-server-tag }}
|
||||
BUILDENV_DOCKERFILE: ${{ inputs.dockerfile }}
|
||||
run: docker build -t "${BUILDENV_IMAGE}:${BUILDENV_TAG}" - < "${BUILDENV_DOCKERFILE}"
|
||||
- name: Save and upload regular image
|
||||
if: ${{ steps.resolve.outputs.needs-build == 'true' }}
|
||||
shell: bash
|
||||
env:
|
||||
GO_VERSION: ${{ inputs.go-version }}
|
||||
BUILDENV_IMAGE: ${{ steps.constants.outputs.image }}
|
||||
BUILDENV_TAG: ${{ inputs.build-server-tag }}
|
||||
BUILDENV_TMPDIR: ${{ steps.constants.outputs.tmpdir }}
|
||||
run: |
|
||||
mkdir -p "${BUILDENV_TMPDIR}"
|
||||
docker save "${BUILDENV_IMAGE}:${GO_VERSION}" | gzip > "${BUILDENV_TMPDIR}/image.tar.gz"
|
||||
docker save "${BUILDENV_IMAGE}:${BUILDENV_TAG}" | gzip > "${BUILDENV_TMPDIR}/image.tar.gz"
|
||||
- name: Upload regular image artifact
|
||||
if: ${{ steps.resolve.outputs.needs-build == 'true' }}
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: ${{ env.BUILDENV_ARTIFACT }}
|
||||
path: ${{ env.BUILDENV_TMPDIR }}/image.tar.gz
|
||||
name: ${{ steps.constants.outputs.artifact }}
|
||||
path: ${{ steps.constants.outputs.tmpdir }}/image.tar.gz
|
||||
retention-days: 1
|
||||
# ── FIPS (skipped on fork PRs) ─────────────────────────────────────
|
||||
- name: Docker Hub login
|
||||
@@ -77,28 +83,33 @@ runs:
|
||||
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
|
||||
shell: bash
|
||||
env:
|
||||
GO_VERSION: ${{ inputs.go-version }}
|
||||
BUILDENV_FIPS_IMAGE: ${{ steps.constants.outputs.fips-image }}
|
||||
BUILDENV_TAG: ${{ inputs.build-server-tag }}
|
||||
run: |
|
||||
docker manifest inspect "${BUILDENV_FIPS_IMAGE}:${GO_VERSION}" > /dev/null 2>&1 || \
|
||||
docker manifest inspect "${BUILDENV_FIPS_IMAGE}:${BUILDENV_TAG}" > /dev/null 2>&1 || \
|
||||
echo "needs-build=true" >> "${GITHUB_OUTPUT}"
|
||||
- name: Build FIPS image
|
||||
if: ${{ steps.resolve-fips.outputs.needs-build == 'true' }}
|
||||
shell: bash
|
||||
env:
|
||||
GO_VERSION: ${{ inputs.go-version }}
|
||||
run: docker build -t "${BUILDENV_FIPS_IMAGE}:${GO_VERSION}" - < "${BUILDENV_FIPS_DOCKERFILE}"
|
||||
BUILDENV_FIPS_IMAGE: ${{ steps.constants.outputs.fips-image }}
|
||||
BUILDENV_TAG: ${{ inputs.build-server-tag }}
|
||||
BUILDENV_FIPS_DOCKERFILE: ${{ inputs.dockerfile-fips }}
|
||||
run: docker build -t "${BUILDENV_FIPS_IMAGE}:${BUILDENV_TAG}" - < "${BUILDENV_FIPS_DOCKERFILE}"
|
||||
- name: Save and upload FIPS image
|
||||
if: ${{ steps.resolve-fips.outputs.needs-build == 'true' }}
|
||||
shell: bash
|
||||
env:
|
||||
GO_VERSION: ${{ inputs.go-version }}
|
||||
BUILDENV_FIPS_IMAGE: ${{ steps.constants.outputs.fips-image }}
|
||||
BUILDENV_TAG: ${{ inputs.build-server-tag }}
|
||||
BUILDENV_TMPDIR: ${{ steps.constants.outputs.tmpdir }}
|
||||
run: |
|
||||
mkdir -p "${BUILDENV_TMPDIR}"
|
||||
docker save "${BUILDENV_FIPS_IMAGE}:${GO_VERSION}" | gzip > "${BUILDENV_TMPDIR}/image-fips.tar.gz"
|
||||
docker save "${BUILDENV_FIPS_IMAGE}:${BUILDENV_TAG}" | gzip > "${BUILDENV_TMPDIR}/image-fips.tar.gz"
|
||||
- name: Upload FIPS image artifact
|
||||
if: ${{ steps.resolve-fips.outputs.needs-build == 'true' }}
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: ${{ env.BUILDENV_FIPS_ARTIFACT }}
|
||||
path: ${{ env.BUILDENV_TMPDIR }}/image-fips.tar.gz
|
||||
name: ${{ steps.constants.outputs.fips-artifact }}
|
||||
path: ${{ steps.constants.outputs.tmpdir }}/image-fips.tar.gz
|
||||
retention-days: 1
|
||||
@@ -8,11 +8,17 @@ on:
|
||||
paths:
|
||||
- server/build/Dockerfile.buildenv
|
||||
- server/build/Dockerfile.buildenv-fips
|
||||
- server/build/buildenv-tag.sh
|
||||
- server/.go-version
|
||||
- .nvmrc
|
||||
- .github/workflows/build-server-image.yml
|
||||
pull_request:
|
||||
paths:
|
||||
- server/build/Dockerfile.buildenv
|
||||
- server/build/Dockerfile.buildenv-fips
|
||||
- server/build/buildenv-tag.sh
|
||||
- server/.go-version
|
||||
- .nvmrc
|
||||
- .github/workflows/build-server-image.yml
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -52,11 +58,11 @@ jobs:
|
||||
run: |
|
||||
docker run --rm mattermost/mattermost-build-server:test /bin/sh -c "go version && node --version"
|
||||
|
||||
- name: buildenv/calculate-golang-version
|
||||
id: go
|
||||
- name: buildenv/calculate-tag
|
||||
id: tag
|
||||
run: |
|
||||
GO_VERSION=$(docker run --rm mattermost/mattermost-build-server:test go version | awk '{print $3}' | sed 's/go//')
|
||||
echo "GO_VERSION=${GO_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
tag=$(./server/build/buildenv-tag.sh)
|
||||
echo "TAG=${tag}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: buildenv/push
|
||||
if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/release-')
|
||||
@@ -67,7 +73,7 @@ jobs:
|
||||
load: false
|
||||
push: true
|
||||
pull: true
|
||||
tags: mattermost/mattermost-build-server:${{ steps.go.outputs.GO_VERSION }}
|
||||
tags: mattermost/mattermost-build-server:${{ steps.tag.outputs.TAG }}
|
||||
|
||||
build-image-fips:
|
||||
permissions:
|
||||
@@ -103,11 +109,11 @@ jobs:
|
||||
run: |
|
||||
docker run --rm --entrypoint bash mattermost/mattermost-build-server-fips:test -c "go version && node --version"
|
||||
|
||||
- name: buildenv/calculate-golang-version
|
||||
id: go
|
||||
- name: buildenv/calculate-tag
|
||||
id: tag
|
||||
run: |
|
||||
GO_VERSION=$(docker run --rm --entrypoint bash mattermost/mattermost-build-server-fips:test -c "go version" | awk '{print $3}' | sed 's/go//')
|
||||
echo "GO_VERSION=${GO_VERSION}" >> "${GITHUB_OUTPUT}"
|
||||
tag=$(./server/build/buildenv-tag.sh)
|
||||
echo "TAG=${tag}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: buildenv/push
|
||||
if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/release-')
|
||||
@@ -118,4 +124,4 @@ jobs:
|
||||
load: false
|
||||
push: true
|
||||
pull: true
|
||||
tags: mattermost/mattermost-build-server-fips:${{ steps.go.outputs.GO_VERSION }}
|
||||
tags: mattermost/mattermost-build-server-fips:${{ steps.tag.outputs.TAG }}
|
||||
@@ -14,7 +14,8 @@ on:
|
||||
logsartifact:
|
||||
required: true
|
||||
type: string
|
||||
go-version:
|
||||
build-server-tag:
|
||||
description: "Build image tag (e.g. go1.26.3-node24.11.1)"
|
||||
required: true
|
||||
type: string
|
||||
fips-enabled:
|
||||
@@ -43,7 +44,6 @@ jobs:
|
||||
COMPOSE_PROJECT_NAME: ghactions
|
||||
INPUT_DATASOURCE: ${{ inputs.datasource }}
|
||||
INPUT_FIPS_ENABLED: ${{ inputs.fips-enabled }}
|
||||
INPUT_GO_VERSION: ${{ inputs.go-version }}
|
||||
INPUT_LOGSARTIFACT: ${{ inputs.logsartifact }}
|
||||
INPUT_NAME: ${{ inputs.name }}
|
||||
INPUT_PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
id: buildenv
|
||||
uses: ./.github/actions/load-buildenv
|
||||
with:
|
||||
go-version: ${{ inputs.go-version }}
|
||||
build-server-tag: ${{ inputs.build-server-tag }}
|
||||
fips-enabled: ${{ inputs.fips-enabled }}
|
||||
- name: Setup log artifact name
|
||||
id: log-artifact
|
||||
|
||||
@@ -25,16 +25,18 @@ jobs:
|
||||
name: Build Environment
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
version: ${{ steps.calculate.outputs.GO_VERSION }}
|
||||
build-server-tag: ${{ steps.calculate.outputs.BUILD_SERVER_TAG }}
|
||||
steps:
|
||||
- name: Checkout mattermost project
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Calculate version
|
||||
- name: Calculate build image tag
|
||||
id: calculate
|
||||
working-directory: server/
|
||||
run: echo GO_VERSION=$(cat .go-version) >> "${GITHUB_OUTPUT}"
|
||||
run: |
|
||||
tag=$(./build/buildenv-tag.sh)
|
||||
echo "BUILD_SERVER_TAG=${tag}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
test-race:
|
||||
name: Race Detector
|
||||
@@ -48,7 +50,7 @@ jobs:
|
||||
datasource: postgres://mmuser:mostest_password@postgres:5432/mattermost_test?sslmode=disable&connect_timeout=10
|
||||
drivername: postgres
|
||||
logsartifact: race-detector-server-test-logs
|
||||
go-version: ${{ needs.buildenv.outputs.version }}
|
||||
build-server-tag: ${{ needs.buildenv.outputs.build-server-tag }}
|
||||
fips-enabled: false
|
||||
fullyparallel: false
|
||||
race-enabled: true
|
||||
|
||||
@@ -26,16 +26,18 @@ jobs:
|
||||
name: Build Environment
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
version: ${{ steps.calculate.outputs.GO_VERSION }}
|
||||
build-server-tag: ${{ steps.calculate.outputs.BUILD_SERVER_TAG }}
|
||||
steps:
|
||||
- name: Checkout mattermost project
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Calculate version
|
||||
- name: Calculate build image tag
|
||||
id: calculate
|
||||
working-directory: server/
|
||||
run: echo GO_VERSION=$(cat .go-version) >> "${GITHUB_OUTPUT}"
|
||||
run: |
|
||||
tag=$(./build/buildenv-tag.sh)
|
||||
echo "BUILD_SERVER_TAG=${tag}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
test-postgres-binary:
|
||||
name: Postgres with binary parameters
|
||||
@@ -49,7 +51,7 @@ jobs:
|
||||
datasource: postgres://mmuser:mostest_password@postgres:5432/mattermost_test?sslmode=disable&connect_timeout=10&binary_parameters=yes
|
||||
drivername: postgres
|
||||
logsartifact: postgres-binary-server-test-logs
|
||||
go-version: ${{ needs.buildenv.outputs.version }}
|
||||
build-server-tag: ${{ needs.buildenv.outputs.build-server-tag }}
|
||||
fips-enabled: false
|
||||
# Unsharded run on a single 8-core runner: fullyparallel=true causes
|
||||
# resource exhaustion (too many server instances, WebSocket hubs, and
|
||||
@@ -71,7 +73,7 @@ jobs:
|
||||
datasource: postgres://mmuser:mostest_password@postgres:5432/mattermost_test?sslmode=disable&connect_timeout=10
|
||||
drivername: postgres
|
||||
logsartifact: postgres-server-fips-test-logs
|
||||
go-version: ${{ needs.buildenv.outputs.version }}
|
||||
build-server-tag: ${{ needs.buildenv.outputs.build-server-tag }}
|
||||
fips-enabled: true
|
||||
# Unsharded run on a single 8-core runner: see note on test-postgres-binary.
|
||||
fullyparallel: false
|
||||
@@ -92,5 +94,5 @@ jobs:
|
||||
datasource: postgres://mmuser:mostest_password@postgres:5432/mattermost_test?sslmode=disable&connect_timeout=10
|
||||
drivername: postgres
|
||||
logsartifact: mmctl-fips-test-logs
|
||||
go-version: ${{ needs.buildenv.outputs.version }}
|
||||
build-server-tag: ${{ needs.buildenv.outputs.build-server-tag }}
|
||||
fips-enabled: true
|
||||
@@ -20,8 +20,8 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
go:
|
||||
name: Compute Go Version
|
||||
buildenv:
|
||||
name: Build Environment
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
actions: write
|
||||
id-token: write # for chainguard (FIPS base image pull)
|
||||
outputs:
|
||||
version: ${{ steps.calculate.outputs.GO_VERSION }}
|
||||
build-server-tag: ${{ steps.calculate.outputs.BUILD_SERVER_TAG }}
|
||||
gomod-changed: ${{ steps.changed-files.outputs.any_changed }}
|
||||
# Individual jobs below use this to skip via `if:` rather
|
||||
# than the workflow being skipped entirely,
|
||||
@@ -40,10 +40,12 @@ jobs:
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Calculate version
|
||||
- name: Calculate build image tag
|
||||
id: calculate
|
||||
working-directory: server/
|
||||
run: echo GO_VERSION=$(cat .go-version) >> "${GITHUB_OUTPUT}"
|
||||
run: |
|
||||
tag=$(./build/buildenv-tag.sh)
|
||||
echo "BUILD_SERVER_TAG=${tag}" >> "${GITHUB_OUTPUT}"
|
||||
- name: Check for go.mod changes
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323 # v47.0.5
|
||||
@@ -61,6 +63,9 @@ jobs:
|
||||
.github/workflows/server-test-template.yml
|
||||
.github/workflows/server-test-merge-template.yml
|
||||
.github/workflows/mmctl-test-template.yml
|
||||
.github/actions/setup-buildenv/**
|
||||
.github/actions/load-buildenv/**
|
||||
.github/actions/run-in-buildenv/**
|
||||
tools/mattermost-govet/**
|
||||
files_ignore: |
|
||||
server/**/*.md
|
||||
@@ -73,11 +78,11 @@ jobs:
|
||||
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
uses: ./.github/actions/setup-buildenv
|
||||
with:
|
||||
go-version: ${{ steps.calculate.outputs.GO_VERSION }}
|
||||
build-server-tag: ${{ steps.calculate.outputs.BUILD_SERVER_TAG }}
|
||||
check-generated:
|
||||
name: Check generated files
|
||||
needs: go
|
||||
if: needs.go.outputs.relevant-changed == 'true'
|
||||
needs: buildenv
|
||||
if: needs.buildenv.outputs.relevant-changed == 'true'
|
||||
runs-on: ubuntu-22.04
|
||||
services:
|
||||
# make default-roles-permissions snapshots a live database.
|
||||
@@ -115,9 +120,9 @@ jobs:
|
||||
fi
|
||||
check-backport-migrations:
|
||||
name: Check backport migrations
|
||||
needs: go
|
||||
needs: buildenv
|
||||
# Only backports (release-* base) must keep a migration's version+name; new master migrations are expected.
|
||||
if: needs.go.outputs.relevant-changed == 'true' && startsWith(github.base_ref, 'release-')
|
||||
if: needs.buildenv.outputs.relevant-changed == 'true' && startsWith(github.base_ref, 'release-')
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout mattermost project
|
||||
@@ -134,8 +139,8 @@ jobs:
|
||||
make check-backport-migrations
|
||||
check-style:
|
||||
name: check-style
|
||||
needs: go
|
||||
if: needs.go.outputs.relevant-changed == 'true'
|
||||
needs: buildenv
|
||||
if: needs.buildenv.outputs.relevant-changed == 'true'
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout mattermost project
|
||||
@@ -147,8 +152,8 @@ jobs:
|
||||
run: make check-style
|
||||
check-mattermost-vet-api:
|
||||
name: Vet API
|
||||
needs: go
|
||||
if: needs.go.outputs.relevant-changed == 'true'
|
||||
needs: buildenv
|
||||
if: needs.buildenv.outputs.relevant-changed == 'true'
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout mattermost project
|
||||
@@ -165,8 +170,8 @@ jobs:
|
||||
# -- Sharded into 4 parallel runners for ~88% wall-time improvement --
|
||||
test-postgres-normal:
|
||||
name: Postgres (shard ${{ matrix.shard }})
|
||||
needs: go
|
||||
if: needs.go.outputs.relevant-changed == 'true'
|
||||
needs: buildenv
|
||||
if: needs.buildenv.outputs.relevant-changed == 'true'
|
||||
strategy:
|
||||
fail-fast: false # Let all shards complete so we get full test results
|
||||
matrix:
|
||||
@@ -184,7 +189,7 @@ jobs:
|
||||
# Each shard gets a unique artifact name so they don't collide
|
||||
logsartifact: "postgres-server-test-logs-shard-${{ matrix.shard }}"
|
||||
enablecoverage: ${{ github.event_name != 'pull_request' || !startsWith(github.event.pull_request.base.ref, 'release-') }}
|
||||
go-version: ${{ needs.go.outputs.version }}
|
||||
build-server-tag: ${{ needs.buildenv.outputs.build-server-tag }}
|
||||
fips-enabled: false
|
||||
shard-index: ${{ matrix.shard }}
|
||||
shard-total: 4
|
||||
@@ -205,8 +210,8 @@ jobs:
|
||||
|
||||
test-elasticsearch-v8:
|
||||
name: Elasticsearch v8 Compatibility
|
||||
needs: go
|
||||
if: needs.go.outputs.relevant-changed == 'true'
|
||||
needs: buildenv
|
||||
if: needs.buildenv.outputs.relevant-changed == 'true'
|
||||
permissions:
|
||||
contents: read
|
||||
actions: write
|
||||
@@ -216,15 +221,15 @@ jobs:
|
||||
datasource: postgres://mmuser:mostest_password@postgres:5432/mattermost_test?sslmode=disable&connect_timeout=10
|
||||
drivername: postgres
|
||||
logsartifact: elasticsearch-v8-server-test-logs
|
||||
go-version: ${{ needs.go.outputs.version }}
|
||||
build-server-tag: ${{ needs.buildenv.outputs.build-server-tag }}
|
||||
fips-enabled: false
|
||||
elasticsearch-version: "8.9.0"
|
||||
test-target: "test-server-elasticsearch"
|
||||
|
||||
test-opensearch-v2:
|
||||
name: OpenSearch v2 Compatibility
|
||||
needs: go
|
||||
if: needs.go.outputs.relevant-changed == 'true'
|
||||
needs: buildenv
|
||||
if: needs.buildenv.outputs.relevant-changed == 'true'
|
||||
permissions:
|
||||
contents: read
|
||||
actions: write
|
||||
@@ -234,7 +239,7 @@ jobs:
|
||||
datasource: postgres://mmuser:mostest_password@postgres:5432/mattermost_test?sslmode=disable&connect_timeout=10
|
||||
drivername: postgres
|
||||
logsartifact: opensearch-v2-server-test-logs
|
||||
go-version: ${{ needs.go.outputs.version }}
|
||||
build-server-tag: ${{ needs.buildenv.outputs.build-server-tag }}
|
||||
fips-enabled: false
|
||||
opensearch-version: "2.19.0"
|
||||
test-target: "test-server-opensearch"
|
||||
@@ -243,10 +248,10 @@ jobs:
|
||||
# Sharded for fast iteration. Weekly workflow provides regular full coverage.
|
||||
test-postgres-normal-fips:
|
||||
if: >-
|
||||
needs.go.outputs.relevant-changed == 'true' &&
|
||||
(contains(github.head_ref, 'fips') || needs.go.outputs.gomod-changed == 'true')
|
||||
needs.buildenv.outputs.relevant-changed == 'true' &&
|
||||
(contains(github.head_ref, 'fips') || needs.buildenv.outputs.gomod-changed == 'true')
|
||||
name: "Postgres FIPS (shard ${{ matrix.shard }})"
|
||||
needs: go
|
||||
needs: buildenv
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -263,7 +268,7 @@ jobs:
|
||||
datasource: postgres://mmuser:mostest_password@postgres:5432/mattermost_test?sslmode=disable&connect_timeout=10
|
||||
drivername: postgres
|
||||
logsartifact: "postgres-server-fips-test-logs-shard-${{ matrix.shard }}"
|
||||
go-version: ${{ needs.go.outputs.version }}
|
||||
build-server-tag: ${{ needs.buildenv.outputs.build-server-tag }}
|
||||
fips-enabled: true
|
||||
shard-index: ${{ matrix.shard }}
|
||||
shard-total: 4
|
||||
@@ -281,8 +286,8 @@ jobs:
|
||||
|
||||
test-mmctl:
|
||||
name: Run mmctl tests
|
||||
needs: go
|
||||
if: needs.go.outputs.relevant-changed == 'true'
|
||||
needs: buildenv
|
||||
if: needs.buildenv.outputs.relevant-changed == 'true'
|
||||
permissions:
|
||||
contents: read
|
||||
actions: write
|
||||
@@ -294,14 +299,14 @@ jobs:
|
||||
datasource: postgres://mmuser:mostest_password@postgres:5432/mattermost_test?sslmode=disable&connect_timeout=10
|
||||
drivername: postgres
|
||||
logsartifact: mmctl-test-logs
|
||||
go-version: ${{ needs.go.outputs.version }}
|
||||
build-server-tag: ${{ needs.buildenv.outputs.build-server-tag }}
|
||||
fips-enabled: false
|
||||
test-mmctl-fips:
|
||||
if: >-
|
||||
needs.go.outputs.relevant-changed == 'true' &&
|
||||
(contains(github.head_ref, 'fips') || needs.go.outputs.gomod-changed == 'true')
|
||||
needs.buildenv.outputs.relevant-changed == 'true' &&
|
||||
(contains(github.head_ref, 'fips') || needs.buildenv.outputs.gomod-changed == 'true')
|
||||
name: Run mmctl tests (FIPS)
|
||||
needs: go
|
||||
needs: buildenv
|
||||
permissions:
|
||||
contents: read
|
||||
actions: write
|
||||
@@ -315,13 +320,13 @@ jobs:
|
||||
datasource: postgres://mmuser:mostest_password@postgres:5432/mattermost_test?sslmode=disable&connect_timeout=10
|
||||
drivername: postgres
|
||||
logsartifact: mmctl-fips-test-logs
|
||||
go-version: ${{ needs.go.outputs.version }}
|
||||
build-server-tag: ${{ needs.buildenv.outputs.build-server-tag }}
|
||||
fips-enabled: true
|
||||
|
||||
build-mattermost-server:
|
||||
name: Build mattermost server app
|
||||
needs: go
|
||||
if: needs.go.outputs.relevant-changed == 'true'
|
||||
needs: buildenv
|
||||
if: needs.buildenv.outputs.relevant-changed == 'true'
|
||||
permissions:
|
||||
contents: read
|
||||
actions: write
|
||||
@@ -370,7 +375,7 @@ jobs:
|
||||
permissions: {}
|
||||
runs-on: ubuntu-22.04
|
||||
needs:
|
||||
- go
|
||||
- buildenv
|
||||
- merge-postgres-test-results
|
||||
- test-elasticsearch-v8
|
||||
- test-opensearch-v2
|
||||
@@ -383,8 +388,8 @@ jobs:
|
||||
run: |
|
||||
# Explicitly fail here rather than relying on `if:`, since a job
|
||||
# skipped via `if:` is reported as "Success" by GitHub.
|
||||
if [ "${{ needs.go.result }}" != "success" ]; then
|
||||
echo "::error::'go' job did not succeed (result: ${{ needs.go.result }}); relevant-changed could not be computed reliably. Failing Server CI Complete."
|
||||
if [ "${{ needs.buildenv.result }}" != "success" ]; then
|
||||
echo "::error::'buildenv' job did not succeed (result: ${{ needs.buildenv.result }}); relevant-changed could not be computed reliably. Failing Server CI Complete."
|
||||
exit 1
|
||||
fi
|
||||
echo "Server CI Complete"
|
||||
@@ -393,7 +398,7 @@ jobs:
|
||||
name: Server CI Report
|
||||
# Skip cleanly (rather than fail) when no relevant Server CI paths
|
||||
# changed, since none of the test jobs it reports on will have run.
|
||||
if: always() && needs.go.outputs.relevant-changed == 'true'
|
||||
if: always() && needs.buildenv.outputs.relevant-changed == 'true'
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
@@ -401,7 +406,7 @@ jobs:
|
||||
pull-requests: write
|
||||
issues: write
|
||||
needs:
|
||||
- go
|
||||
- buildenv
|
||||
- ci-complete
|
||||
uses: ./.github/workflows/server-ci-report.yml
|
||||
secrets:
|
||||
@@ -421,7 +426,7 @@ jobs:
|
||||
# (and thus server-dist-artifact) will not have run.
|
||||
if: >-
|
||||
success('ci-complete') &&
|
||||
needs.go.outputs.relevant-changed == 'true' &&
|
||||
needs.buildenv.outputs.relevant-changed == 'true' &&
|
||||
github.repository_owner == 'mattermost' &&
|
||||
github.event_name == 'pull_request' &&
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
@@ -430,7 +435,7 @@ jobs:
|
||||
actions: read
|
||||
statuses: write
|
||||
needs:
|
||||
- go
|
||||
- buildenv
|
||||
- ci-complete
|
||||
uses: ./.github/workflows/server-ci-artifacts.yml
|
||||
secrets:
|
||||
|
||||
@@ -26,7 +26,8 @@ on:
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
go-version:
|
||||
build-server-tag:
|
||||
description: "Build image tag (e.g. go1.26.3-node24.11.1)"
|
||||
required: true
|
||||
type: string
|
||||
fips-enabled:
|
||||
@@ -90,7 +91,6 @@ jobs:
|
||||
INPUT_ENABLECOVERAGE: ${{ inputs.enablecoverage }}
|
||||
INPUT_FIPS_ENABLED: ${{ inputs.fips-enabled }}
|
||||
INPUT_FULLYPARALLEL: ${{ inputs.fullyparallel }}
|
||||
INPUT_GO_VERSION: ${{ inputs.go-version }}
|
||||
INPUT_LOGSARTIFACT: ${{ inputs.logsartifact }}
|
||||
INPUT_NAME: ${{ inputs.name }}
|
||||
INPUT_PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
@@ -114,7 +114,7 @@ jobs:
|
||||
id: buildenv
|
||||
uses: ./.github/actions/load-buildenv
|
||||
with:
|
||||
go-version: ${{ inputs.go-version }}
|
||||
build-server-tag: ${{ inputs.build-server-tag }}
|
||||
fips-enabled: ${{ inputs.fips-enabled }}
|
||||
|
||||
- name: Restore test timing data
|
||||
@@ -180,7 +180,7 @@ jobs:
|
||||
if: inputs.shard-total > 1
|
||||
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
|
||||
with:
|
||||
go-version: ${{ inputs.go-version }}
|
||||
go-version-file: server/.go-version
|
||||
|
||||
- name: Split tests across shards
|
||||
if: inputs.shard-total > 1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
FROM golang:1.26.7-bookworm@sha256:6ef6e30f0ea5c384f6d111cf856e024e3086bbdcb1779da3f3b3fbba0aea53d2
|
||||
ARG NODE_VERSION=20.11.1
|
||||
ARG NODE_VERSION=24.11.1
|
||||
|
||||
RUN apt-get update && apt-get install -y make git apt-transport-https ca-certificates curl software-properties-common build-essential zip xmlsec1 jq pgloader gnupg
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
FROM cgr.dev/mattermost.com/go-msft-fips:1.26.7.1-dev@sha256:ae345a37a612265894a7e7f318be45680663346cb7992613916e196daf38e839
|
||||
ARG NODE_VERSION=20.11.1
|
||||
ARG NODE_VERSION=24.11.1
|
||||
|
||||
RUN apk add curl ca-certificates mailcap unrtf wv poppler-utils tzdata gpg xmlsec
|
||||
|
||||
|
||||
Executable
+57
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env bash
|
||||
# Prints the tag identifying the mattermost-build-server image, e.g.
|
||||
# "go1.26.7-node24.11.1". The image bakes in both toolchains, so the tag names
|
||||
# both. CI resolves this once and propagates it as BUILD_SERVER_TAG.
|
||||
#
|
||||
# The tag comes from the Dockerfiles, since those are what actually determine
|
||||
# the image, and they are checked against .go-version and .nvmrc so the pins
|
||||
# cannot drift apart unnoticed.
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")/../.."
|
||||
|
||||
DOCKERFILES=(server/build/Dockerfile.buildenv server/build/Dockerfile.buildenv-fips)
|
||||
|
||||
fail() {
|
||||
echo "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# A pin may be more specific than its source of truth: the FIPS base image
|
||||
# carries a fourth component, 1.26.7.1 for Go 1.26.7.
|
||||
satisfies() {
|
||||
[[ "$1" == "$2" || "$1" == "$2."* ]]
|
||||
}
|
||||
|
||||
go_version=$(cat server/.go-version)
|
||||
node_spec=$(cat .nvmrc)
|
||||
|
||||
node_version=""
|
||||
for dockerfile in "${DOCKERFILES[@]}"; do
|
||||
from=$(awk '$1 == "FROM" { print $2; exit }' "${dockerfile}")
|
||||
[[ -n "${from}" ]] || fail "${dockerfile}: no FROM"
|
||||
base_version="${from#*:}"
|
||||
base_version="${base_version%%@*}"
|
||||
base_version="${base_version%-*}"
|
||||
satisfies "${base_version}" "${go_version}" ||
|
||||
fail "${dockerfile}: base image is Go ${base_version}, but server/.go-version says ${go_version}"
|
||||
|
||||
version=$(awk -F= '$1 == "ARG NODE_VERSION" { print $2; exit }' "${dockerfile}")
|
||||
[[ -n "${version}" ]] || fail "${dockerfile}: no ARG NODE_VERSION"
|
||||
satisfies "${version}" "${node_spec}" ||
|
||||
fail "${dockerfile}: ARG NODE_VERSION is ${version}, but .nvmrc says ${node_spec}"
|
||||
|
||||
# A single tag covers both images, so they have to agree.
|
||||
if [[ -n "${node_version}" && "${version}" != "${node_version}" ]]; then
|
||||
fail "${DOCKERFILES[0]} has Node ${node_version} but ${dockerfile} has ${version}"
|
||||
fi
|
||||
node_version="${version}"
|
||||
done
|
||||
|
||||
tag="go${go_version}-node${node_version}"
|
||||
|
||||
# CI interpolates this tag into shell commands and workflow files, so refuse
|
||||
# anything that isn't a well-formed Docker tag.
|
||||
[[ "${tag}" =~ ^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$ ]] || fail "invalid tag: ${tag}"
|
||||
|
||||
echo "${tag}"
|
||||
Reference in new issue
Block a user