* 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
Mattermost is an open core, self-hosted collaboration platform that offers chat, workflow automation, voice calling, screen sharing, and AI integration. This repo is the primary source for core development on the Mattermost platform; it's written in Go and React, runs as a single Linux binary, and relies on PostgreSQL. A new compiled version is released under an MIT license every month on the 16th.
Deploy Mattermost on-premises, or try it for free in the cloud.
Learn more about the following use cases with Mattermost:
Other useful resources:
- Download and Install Mattermost - Install, setup, and configure your own Mattermost instance.
- Product documentation - Learn how to run a Mattermost instance and take advantage of all the features.
- Developer documentation - Contribute code to Mattermost or build an integration via APIs, Webhooks, slash commands, Apps, and plugins.
Table of contents
- Install Mattermost
- Native mobile and desktop apps
- Get security bulletins
- Get involved
- Learn more
- License
- Get the latest news
- Contributing
Install Mattermost
- Download and Install Mattermost Self-Hosted - Deploy a Mattermost Self-hosted instance in minutes via Docker, Ubuntu, or tar.
- Get started in the cloud to try Mattermost today.
- Developer machine setup - Follow this guide if you want to write code for Mattermost.
Other install guides:
- Deploy Mattermost on Docker
- Mattermost Omnibus
- Install Mattermost from Tar
- Ubuntu 20.04 LTS
- Kubernetes
- Helm
- More server install guides
Native mobile and desktop apps
In addition to the web interface, you can also download Mattermost clients for Android, iOS, Windows PC, macOS, and Linux.
Get security bulletins
Receive notifications of critical security updates. The sophistication of online attackers is perpetually increasing. If you're deploying Mattermost it's highly recommended you subscribe to the Mattermost Security Bulletin mailing list for updates on critical security releases.
Get involved
- Contribute to Mattermost
- Find "Help Wanted" projects
- Join Developer Discussion on a Mattermost server for contributors
- Get Help With Mattermost
Learn more
- API options - webhooks, slash commands, drivers, and web service
- See who's using Mattermost
- Browse over 700 Mattermost integrations
License
See the LICENSE file for license rights and limitations.
Get the latest news
- X - Follow Mattermost on X, formerly Twitter.
- Blog - Get the latest updates from the Mattermost blog.
- Facebook - Follow Mattermost on Facebook.
- LinkedIn - Follow Mattermost on LinkedIn.
- Email - Subscribe to our newsletter (1 or 2 per month).
- Mattermost - Join the ~contributors channel on the Mattermost Community Server.
- IRC - Join the #matterbridge channel on Freenode (thanks to matterircd).
- YouTube - Subscribe to Mattermost.
Contributing
Please see CONTRIBUTING.md. Join the Mattermost Contributors server to join community discussions about contributions, development, and more.




