Skip to content
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e1587cc
Add in-repo Complement test to sanity check Synapse version matches g…
MadLittleMods Feb 18, 2026
59df0d6
Better comments
MadLittleMods Feb 18, 2026
49d2d27
Add tests for `parseSynapseVersionString`
MadLittleMods Feb 18, 2026
ce1ae57
Working `parseSynapseVersionString`
MadLittleMods Feb 18, 2026
5189af9
Run git commands
MadLittleMods Feb 18, 2026
77ed60f
`getVersionFromPyproject`
MadLittleMods Feb 18, 2026
991ab59
Better error message
MadLittleMods Feb 18, 2026
639402b
Fix dirty checkout command
MadLittleMods Feb 18, 2026
29029e5
Add changelog
MadLittleMods Feb 18, 2026
5293622
Try adding `.git` data
MadLittleMods Feb 18, 2026
bc2c676
Revert "Try adding `.git` data"
MadLittleMods Feb 18, 2026
aef8a88
Pretty print structs we compare
MadLittleMods Feb 18, 2026
b58aab6
Start of `SYNAPSE_VERSION`
MadLittleMods Feb 19, 2026
6ce2ca2
Fix `SYNAPSE_VERSION` not appearing under `/usr/local/lib/python3.13/…
MadLittleMods Feb 20, 2026
5d1a25f
Read from file
MadLittleMods Feb 20, 2026
4b33f3f
Remove `SYNAPSE_VERSION` file strategy
MadLittleMods Feb 20, 2026
e8c5bad
Read from environment variable
MadLittleMods Feb 20, 2026
944611c
Update docstring
MadLittleMods Feb 20, 2026
ddfbbf8
Fix lints
MadLittleMods Feb 20, 2026
b7bd4be
Simplify test
MadLittleMods Feb 20, 2026
c7cb45d
Better text
MadLittleMods Mar 2, 2026
107066c
`PR's` -> `PRs`
MadLittleMods Mar 5, 2026
0b5cb91
Remove double `be` typo
MadLittleMods Mar 5, 2026
3f7f4f5
Fix `overridden` typo
MadLittleMods Mar 5, 2026
b1a651e
Remove `egg-info` to get accurate Synapse version string
MadLittleMods Mar 5, 2026
f2c92ec
Update CI
MadLittleMods Mar 5, 2026
7bdc821
Kick CI again
MadLittleMods Mar 5, 2026
296ba32
Make Poetry (version 2.2.1)
MadLittleMods Mar 5, 2026
957d5c3
Point to Synapse checkout
MadLittleMods Mar 5, 2026
c28cd6c
Move closer to Synapse step
MadLittleMods Mar 5, 2026
7b199ab
Formatting would be nice because JSON is hard to read
MadLittleMods Mar 5, 2026
5dd4805
Test is in repo
MadLittleMods Mar 5, 2026
4109f09
Merge branch 'develop' into madlittlemods/sanity-check-complement-image
MadLittleMods Mar 5, 2026
c5c5465
Merge branch 'develop' into madlittlemods/sanity-check-complement-image
MadLittleMods Mar 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -707,28 +707,28 @@ jobs:
cache-dependency-path: complement/go.sum

@MadLittleMods MadLittleMods Mar 2, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is purposely not up to date with the develop at the moment so I can still reproduce the problem from #19475

@MadLittleMods MadLittleMods Mar 5, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol, trying to get this new test to fail in CI but it looks like GitHub Current runner version: '2.332.0' is back to using Docker Client/Server 28.0.4 (source) which doesn't have the problem.

Versus the previous GitHub Current runner version: '2.331.0' we saw in #19475 which was using Docker Client/Server 29.1.5 (source)

Looks like this was reverted in actions/runner-images#13708

go-version-file: complement/go.mod

- name: Run Complement Tests
id: run_complement_tests
# -p=1: We're using `-p 1` to force the test packages to run serially as GHA boxes
# are underpowered and don't like running tons of Synapse instances at once.
# -json: Output JSON format so that gotestfmt can parse it.
#
# tee /tmp/gotest-complement.log: We tee the output to a file so that we can re-process it
# later on for better formatting with gotestfmt. But we still want the command
# to output to the terminal as it runs so we can see what's happening in
# real-time.
run: |
set -o pipefail
COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -p 1 -json 2>&1 | tee /tmp/gotest-complement.log
shell: bash
env:
POSTGRES: ${{ (matrix.database == 'Postgres') && 1 || '' }}
WORKERS: ${{ (matrix.arrangement == 'workers') && 1 || '' }}

- name: Formatted Complement test logs
# Always run this step if we attempted to run the Complement tests.
if: always() && steps.run_complement_tests.outcome != 'skipped'
run: cat /tmp/gotest-complement.log | gotestfmt -hide "successful-downloads,empty-packages"
# - name: Run Complement Tests
# id: run_complement_tests
# # -p=1: We're using `-p 1` to force the test packages to run serially as GHA boxes
# # are underpowered and don't like running tons of Synapse instances at once.
# # -json: Output JSON format so that gotestfmt can parse it.
# #
# # tee /tmp/gotest-complement.log: We tee the output to a file so that we can re-process it
# # later on for better formatting with gotestfmt. But we still want the command
# # to output to the terminal as it runs so we can see what's happening in
# # real-time.
# run: |
# set -o pipefail
# COMPLEMENT_DIR=`pwd`/complement synapse/scripts-dev/complement.sh -p 1 -json 2>&1 | tee /tmp/gotest-complement.log
# shell: bash
# env:
# POSTGRES: ${{ (matrix.database == 'Postgres') && 1 || '' }}
# WORKERS: ${{ (matrix.arrangement == 'workers') && 1 || '' }}

# - name: Formatted Complement test logs
# # Always run this step if we attempted to run the Complement tests.
# if: always() && steps.run_complement_tests.outcome != 'skipped'
# run: cat /tmp/gotest-complement.log | gotestfmt -hide "successful-downloads,empty-packages"
Comment thread
MadLittleMods marked this conversation as resolved.
Outdated

- name: Run in-repo Complement Tests
id: run_in_repo_complement_tests
Expand Down
1 change: 1 addition & 0 deletions changelog.d/19476.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add in-repo Complement test to sanity check Synapse version matches git checkout (testing what we think we are).
1 change: 1 addition & 0 deletions complement/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ require (
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 // indirect
Comment thread
reivilibre marked this conversation as resolved.
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/term v0.5.2 // indirect
Expand Down
12 changes: 12 additions & 0 deletions complement/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
github.com/hashicorp/go-set/v3 v3.0.0 h1:CaJBQvQCOWoftrBcDt7Nwgo0kdpmrKxar/x2o6pV9JA=
github.com/hashicorp/go-set/v3 v3.0.0/go.mod h1:IEghM2MpE5IaNvL+D7X480dfNtxjRXZ6VMpK3C8s2ok=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
Expand All @@ -50,6 +52,8 @@ github.com/matrix-org/gomatrixserverlib v0.0.0-20250813150445-9f5070a65744 h1:5G
github.com/matrix-org/gomatrixserverlib v0.0.0-20250813150445-9f5070a65744/go.mod h1:b6KVfDjXjA5Q7vhpOaMqIhFYvu5BuFVZixlNeTV/CLc=
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 h1:6z4KxomXSIGWqhHcfzExgkH3Z3UkIXry4ibJS4Aqz2Y=
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66/go.mod h1:iBI1foelCqA09JJgPV0FYz4qA5dUXYOxMi57FxKBdd4=
github.com/miekg/dns v1.1.66 h1:FeZXOS3VCVsKnEAd+wBkjMC3D2K+ww66Cq3VnCINuJE=
github.com/miekg/dns v1.1.66/go.mod h1:jGFzBsSNbJw6z1HYut1RKBKHA9PBdxeHrZG8J+gC2WE=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
Expand Down Expand Up @@ -120,6 +124,8 @@ golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
Expand All @@ -129,6 +135,8 @@ golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand All @@ -147,6 +155,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand All @@ -160,6 +170,8 @@ google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3i
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
101 changes: 101 additions & 0 deletions complement/tests/synapse_version_check_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// This file is licensed under the Affero General Public License (AGPL) version 3.
//
// Copyright (C) 2026 Element Creations Ltd
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// See the GNU Affero General Public License for more details:
// <https://www.gnu.org/licenses/agpl-3.0.html>.

package synapse_tests

import (
"net/http"
"os/exec"
"strings"
"testing"

"github.com/matrix-org/complement"
"github.com/matrix-org/complement/match"
"github.com/matrix-org/complement/must"
"github.com/tidwall/gjson"
)

func TestSynapseVersion(t *testing.T) {
deployment := complement.Deploy(t, 1)
defer deployment.Destroy(t)

unauthedClient := deployment.UnauthenticatedClient(t, "hs1")

// Sanity check that the version of Synapse used in the `COMPLEMENT_BASE_IMAGE`
// matches the same git commit we have checked out. This ensures that the image being
// used in Complement is the one that we just built locally with `complement.sh`
// instead of accidentally pulling in some remote one.
//
// This test is expected to pass if you use `complement.sh`.
//
// If this test fails, it probably means that Complement is using an image that
// doesn't encompass the changes you have checked out (unexpected). We want to yell
// loudly and point out what's wrong instead of silently letting your PR's pass
// without actually being tested.
t.Run("Synapse version matches current git checkout", func(t *testing.T) {
// Get the Synapse version details of the current git checkout
checkoutSynapseVersion := runCommand(
t,
[]string{
"poetry",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's not necessarily a given that people will have poetry if our uv plans pick up any momentum at all. However I'm also happy to leave this easy fix for when it's actually a problem.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect this to be updated to whatever our developer flow is ⏩

"run",
"python",
"-c",
"from synapse.util import SYNAPSE_VERSION; print(SYNAPSE_VERSION)",
},
)

// Find the version details of the Synapse instance deployed from the Docker image
res := unauthedClient.MustDo(t, "GET", []string{"_matrix", "federation", "v1", "version"})
Comment thread
MadLittleMods marked this conversation as resolved.
body := must.MatchResponse(t, res, match.HTTPResponse{
StatusCode: http.StatusOK,
JSON: []match.JSON{
match.JSONKeyPresent("server"),
},
})
rawSynapseVersionString := gjson.GetBytes(body, "server.version").Str
t.Logf(
"Synapse version string from federation version endpoint: %s",
rawSynapseVersionString,
)

must.Equal(
t,
rawSynapseVersionString,
checkoutSynapseVersion,
"Synapse version in the checkout doesn't match the Synapse version that Complement is running. "+
"If this test fails, it probably means that Complement is using an image that "+
"doesn't encompass the changes you have checked out (unexpected). We want to yell "+
"loudly and point out what's wrong instead of silently letting your PR's pass "+
Comment thread
MadLittleMods marked this conversation as resolved.
Outdated
"without actually being tested.",
)
})
}

// runCommand will run the given command and return the stdout (whitespace
// trimmed).
func runCommand(t *testing.T, commandPieces []string) string {
t.Helper()

// Then run our actual command
cmd := exec.Command(commandPieces[0], commandPieces[1:]...)
output, err := cmd.Output()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider cmd.CombinedOutput() to get stderr as well. Currently I think stderr output would go uncaptured?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's expected as we just want the machine-readable/pipeable values from stdout

Although I don't think it matters in this case with the command we're using.

Ideally, we'd print everything when the command fails 👍

if err != nil {
t.Fatalf(
"runCommand: failed to run command (%s): %v",
strings.Join(commandPieces, " "),
err,
)
}

return strings.TrimSpace(string(output))
}
8 changes: 8 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,14 @@ FROM docker.io/library/python:${PYTHON_VERSION}-slim-${DEBIAN_VERSION}

ARG TARGETARCH

# If specified, Synapse will use this as the version string in the app.
#
# This can be useful to capture the git info of the build as `.git/` won't be be
Comment thread
MadLittleMods marked this conversation as resolved.
Outdated
# available in the Docker image for Synapse to generate from.
ARG SYNAPSE_VERSION_STRING
# Pass it through to Synapse as an environment variable.
ENV SYNAPSE_VERSION_STRING=${SYNAPSE_VERSION_STRING}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(had to look up that this is actually optional, seems like it is)


LABEL org.opencontainers.image.url='https://github.com/element-hq/synapse'
LABEL org.opencontainers.image.documentation='https://element-hq.github.io/synapse/latest/'
LABEL org.opencontainers.image.source='https://github.com/element-hq/synapse.git'
Expand Down
2 changes: 2 additions & 0 deletions scripts-dev/complement.sh
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,12 @@ main() {
$CONTAINER_RUNTIME run --rm -v $editable_mount --entrypoint 'cp' complement-synapse-editable -- /synapse_rust.abi3.so.bak /editable-src/synapse/synapse_rust.abi3.so

else
synapse_version_string="$(poetry run python -c 'from synapse.util import SYNAPSE_VERSION; print(SYNAPSE_VERSION)')"
Comment thread
MadLittleMods marked this conversation as resolved.

# Build the base Synapse image from the local checkout
echo_if_github "::group::Build Docker image: matrixdotorg/synapse"
$CONTAINER_RUNTIME build -t matrixdotorg/synapse \
--build-arg SYNAPSE_VERSION_STRING="$synapse_version_string" \
--build-arg TEST_ONLY_SKIP_DEP_HASH_VERIFICATION \
--build-arg TEST_ONLY_IGNORE_POETRY_LOCKFILE \
-f "docker/Dockerfile" .
Expand Down
13 changes: 10 additions & 3 deletions synapse/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import collections.abc
import logging
import os
import typing
from typing import (
Iterator,
Expand Down Expand Up @@ -74,9 +75,15 @@ def log_failure(
return None


# Version string with git info. Computed here once so that we don't invoke git multiple
# times.
SYNAPSE_VERSION = get_distribution_version_string("matrix-synapse", __file__)
SYNAPSE_VERSION = os.getenv(
"SYNAPSE_VERSION_STRING"
) or get_distribution_version_string("matrix-synapse", __file__)
"""
Version string with git info.

This can be overriden via the `SYNAPSE_VERSION_STRING` environment variable or is
Comment thread
MadLittleMods marked this conversation as resolved.
Outdated
computed here once so that we don't invoke git multiple times.
"""


class ExceptionBundle(Exception):
Expand Down