Add complement and tests to CI

This commit is contained in:
MTRNord 2023-12-02 22:24:24 +01:00
parent 37df08df0b
commit 87fe7a3bb7
No known key found for this signature in database
12 changed files with 230 additions and 17 deletions

View File

@ -56,14 +56,6 @@ jobs:
with:
languages: ${{ matrix.language }}
# # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
# # If this step fails, then you should remove it and run the build manually (see below)
# - name: Autobuild
# uses: github/codeql-action/autobuild@v2
# env:
# CC: /usr/bin/clang-17
# CCX: /usr/bin/clang++-17
- name: Build
run: |
/usr/bin/clang++-17 --version

122
.github/workflows/tests.yml vendored Normal file
View File

@ -0,0 +1,122 @@
name: Tests
on:
push:
branches:
- main
pull_request:
release:
types: [published]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
tests:
name: Tests
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@v4
- name: Install dependencies
run: |
sudo ./.github/llvm.sh 17 all
which clang-17
which clang++-17
sudo apt install -y ninja-build nlohmann-json3-dev libpq-dev libsodium-dev libjsoncpp-dev uuid-dev zlib1g-dev openssl libssl-dev
sudo pip3 install meson
pushd /tmp
git clone https://github.com/drogonframework/drogon
pushd drogon
git submodule update --init
mkdir build
pushd build
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_POSTGRESQL=ON -DBUILD_REDIS=OFF -DBUILD_SQLITE=OFF -DBUILD_MYSQL=OFF -DBUILD_ORM=ON -DBUILD_SHARED_LIBS=ON ..
make && sudo make install
sudo ln -s /usr/local/lib/libdrogon.so.1 /usr/lib/libdrogon.so.1
sudo ln -s /usr/local/lib/libtrantor.so.1 /usr/lib/libtrantor.so.1
popd
popd
- name: Test
run: |
/usr/bin/clang++-17 --version
CC=/usr/bin/clang-17 CXX=/usr/bin/clang++-17 meson setup --reconfigure --buildtype=release -Db_lto=false -Db_thinlto_cache=false builddir
pushd builddir
CC=/usr/bin/clang-17 CXX=/usr/bin/clang++-17 meson test
popd
# run Complement
complement:
name: "Complement (${{ matrix.label }})"
timeout-minutes: 20
needs: tests
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- label: PostgreSQL
postgres: Postgres
steps:
# Env vars are set file a file given by $GITHUB_PATH. We need both Go 1.17 and GOPATH on env to run Complement.
# See https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-system-path
- name: "Set Go Version"
run: |
echo "$GOROOT_1_17_X64/bin" >> $GITHUB_PATH
echo "~/go/bin" >> $GITHUB_PATH
- name: "Install Complement Dependencies"
# We don't need to install Go because it is included on the Ubuntu 20.04 image:
# See https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-Readme.md specifically GOROOT_1_17_X64
run: |
sudo apt-get update && sudo apt-get install -y libolm3 libolm-dev
go get -v github.com/haveyoudebuggedit/gotestfmt/v2/cmd/gotestfmt@latest
- name: Run actions/checkout@v4 for persephone
uses: actions/checkout@v4
with:
path: persephone
# Attempt to check out the same branch of Complement as the PR. If it
# doesn't exist, fallback to main.
- name: Checkout complement
shell: bash
run: |
mkdir -p complement
# Attempt to use the version of complement which best matches the current
# build. Depending on whether this is a PR or release, etc. we need to
# use different fallbacks.
#
# 1. First check if there's a similarly named branch (GITHUB_HEAD_REF
# for pull requests, otherwise GITHUB_REF).
# 2. Attempt to use the base branch, e.g. when merging into release-vX.Y
# (GITHUB_BASE_REF for pull requests).
# 3. Use the default complement branch ("master").
for BRANCH_NAME in "$GITHUB_HEAD_REF" "$GITHUB_BASE_REF" "${GITHUB_REF#refs/heads/}" "master"; do
# Skip empty branch names and merge commits.
if [[ -z "$BRANCH_NAME" || $BRANCH_NAME =~ ^refs/pull/.* ]]; then
continue
fi
(wget -O - "https://github.com/matrix-org/complement/archive/$BRANCH_NAME.tar.gz" | tar -xz --strip-components=1 -C complement) && break
done
# This doesn't exist upstream
cp persephone/complement/hs_persephone.go complement/runtime/
# Build initial Persephone image
- run: docker build -t complement-persephone -f complement/Dockerfile .
working-directory: persephone
# Run Complement
- run: |
set -o pipefail &&
go test -v -json -tags persephone_blacklist ./tests/... 2>&1 | gotestfmt
shell: bash
name: Run Complement Tests
env:
COMPLEMENT_BASE_IMAGE: complement-persephone:latest
API: ${{ matrix.api && 1 }}
working-directory: complement

2
.gitignore vendored
View File

@ -6,7 +6,7 @@ subprojects/*
.idea
config.yaml
/config.yaml
codeql_db
_codeql_build_dir

View File

@ -1,5 +1,5 @@
{
"C_Cpp.default.compileCommands": "builddir/compile_commands.json",
"C_Cpp.default.compileCommands": "/media/marcel/1ac60e61-e5e2-4157-9a7a-830801a3fb0b/projects/persephone/builddir/compile_commands.json",
"files.associations": {
"*.embeddedhtml": "html",
"*.rs": "rust",

50
complement/Dockerfile Normal file
View File

@ -0,0 +1,50 @@
FROM python:3.12-bookworm
RUN apt-get update && apt-get install -y postgresql cmake nlohmann-json3-dev libpq-dev libsodium-dev libjsoncpp-dev uuid-dev zlib1g-dev openssl libssl-dev git
WORKDIR /build
# No password when connecting over localhost
RUN sed -i "s%127.0.0.1/32 md5%127.0.0.1/32 trust%g" /etc/postgresql/15/main/pg_hba.conf && \
# Bump up max conns for moar concurrency
sed -i 's/max_connections = 100/max_connections = 2000/g' /etc/postgresql/15/main/postgresql.conf
# This entry script starts postgres, waits for it to be up then starts persephone
RUN echo '\
#!/bin/bash -eu \n\
pg_lsclusters \n\
pg_ctlcluster 15 main start \n\
\n\
until pg_isready \n\
do \n\
echo "Waiting for postgres"; \n\
sleep 1; \n\
done \n\
' > run_postgres.sh && chmod +x run_postgres.sh
# we will dump the binaries and config file to this location to ensure any local untracked files
# that come from the COPY . . file don't contaminate the build
RUN mkdir /persephone
COPY .
COPY .github/llvm.sh .
RUN sudo ./llvm.sh 17 all && which clang-17 && which clang++-17
RUN pip3 install meson ninja
# Install drogon
RUN pushd /tmp && git clone https://github.com/drogonframework/drogon && pushd drogon && git submodule update --init && mkdir build && pushd build && cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_POSTGRESQL=ON -DBUILD_REDIS=OFF -DBUILD_SQLITE=OFF -DBUILD_MYSQL=OFF -DBUILD_ORM=ON -DBUILD_SHARED_LIBS=ON .. && make && sudo make install && sudo ln -s /usr/local/lib/libdrogon.so.1 /usr/lib/libdrogon.so.1 && sudo ln -s /usr/local/lib/libtrantor.so.1 /usr/lib/libtrantor.so.1 && popd && popd && popd
# Build and install persephone
RUN CC=/usr/bin/clang-17 CXX=/usr/bin/clang++-17 meson setup --reconfigure --buildtype=release -Db_lto=false -Db_thinlto_cache=false builddir && pushd builddir && meson compile && popd
WORKDIR /build/builddir
ENV SERVER_NAME=localhost
EXPOSE 8008 8448
# At runtime, generate TLS cert based on the CA now mounted at /ca
# At runtime, replace the SERVER_NAME with what we are told
CMD /build/run_postgres.sh && openssl genrsa -out server.key 2048 && \
openssl req -new -sha256 -key server.key -subj "/C=DE/ST=CA/O=MyOrg, Inc./CN=$SERVER_NAME" -out server.csr && \
openssl x509 -req -in server.csr -CA /complement/ca/ca.crt -CAkey /complement/ca/ca.key -CAcreateserial -out server.crt -days 1 -sha256 && \
cp /build/complement/config.yaml ./config.yaml && \
cp /complement/ca/ca.crt /usr/local/share/ca-certificates/ && update-ca-certificates && \
./persephone

11
complement/config.yaml Normal file
View File

@ -0,0 +1,11 @@
database:
host: localhost
port: 5432
database_name: postgres
user: postgres
password: ""
matrix:
server_name: localhost
server_key_location: ./server_key.key
webserver:
ssl: true

View File

@ -0,0 +1,11 @@
// +build persephone_blacklist
package runtime
const (
Persephone = "persephone"
)
func init() {
Homeserver = Persephone
}

View File

@ -1,5 +1,11 @@
database:
url: "postgres://user@domain"
pool_size: 15
host: localhost
port: 5432
database_name: persephone
user: persephone
password: ""
matrix:
server_name: example.com
server_name: localhost
server_key_location: ./server_key.key
webserver:
ssl: false

View File

@ -24,6 +24,7 @@ add_project_arguments(
'-Wshadow',
'-Wconversion',
'-Wpedantic',
'-Wunitialized',
'-DWITH_BOOST=OFF',
'-D_FORTIFY_SOURCE=2',
#'-fno-sanitize=vptr',

View File

@ -44,6 +44,11 @@ int main() {
db.migrate();
});
if (config.webserver_config.ssl) {
drogon::app().addListener("0.0.0.0", 8448, true, "./server.crt",
"./server.key", false);
}
drogon::app().run();
} catch (YAML::BadFile &error) {
LOG_ERROR << "Missing or invalid config.yaml file. Make sure to create it "

View File

@ -13,9 +13,10 @@ Config::Config() {
YAML::Node config = YAML::LoadFile("config.yaml");
this->load_db(config);
this->load_matrix(config);
this->load_webserver(config);
}
void Config::load_db(YAML::Node config) {
void Config::load_db(const YAML::Node &config) {
if (!config["database"]) {
throw std::runtime_error("Missing 'database' section. Unable to start.");
}
@ -55,7 +56,7 @@ void Config::load_db(YAML::Node config) {
this->db_config.password = config["database"]["password"].as<std::string>();
}
void Config::load_matrix(YAML::Node config) {
void Config::load_matrix(const YAML::Node &config) {
if (!config["matrix"]) {
throw std::runtime_error("Missing 'matrix' section. Unable to start.");
}
@ -78,4 +79,12 @@ void Config::load_matrix(YAML::Node config) {
auto server_key_location =
config["matrix"]["server_key_location"].as<std::string>();
this->matrix_config.server_key_location = server_key_location;
}
void Config::load_webserver(const YAML::Node &config) {
if (config["ssl"]) {
this->webserver_config.ssl = config["ssl"].as<bool>();
} else {
this->webserver_config.ssl = false;
}
}

View File

@ -17,6 +17,10 @@ struct [[nodiscard]] DBConfig {
std::string password;
};
struct [[nodiscard]] WebserverConfig {
bool ssl;
};
struct [[nodiscard]] MatrixConfig {
std::string server_name;
std::filesystem::path server_key_location;
@ -25,10 +29,12 @@ struct [[nodiscard]] MatrixConfig {
struct [[nodiscard]] Config {
DBConfig db_config;
MatrixConfig matrix_config;
WebserverConfig webserver_config;
Config();
private:
void load_db(YAML::Node config);
void load_matrix(YAML::Node config);
void load_db(const YAML::Node &config);
void load_matrix(const YAML::Node &config);
void load_webserver(const YAML::Node &config);
};