diff --git a/.github/jobs/base.sh b/.github/jobs/base.sh new file mode 100755 index 00000000000..b0fdbb65a2f --- /dev/null +++ b/.github/jobs/base.sh @@ -0,0 +1,93 @@ +#!/bin/bash + +set -x + +. .github/jobs/data/gha_ci_bashrc + +lsb_release -a + +cat > ~/.my.cnf < etc/dbpasswords.secret + +# Generate APP_SECRET for symfony +# shellcheck disable=SC2164 +( cd etc ; ./gensymfonysecret > symfony_app.secret ) + +cat > webapp/config/static.yaml <> ~www-data/.netrc +sudo -u www-data bin/dj_setup_database -uroot -pdomjudge bare-install + +# shellcheck disable=SC2154 +if [ -n "${integration:-}" ]; then + # Make sure admin has a team associated to insert submissions as well. + echo "UPDATE user SET teamid=1 WHERE userid=1;" | mysql domjudge +fi + +sudo -u www-data bin/dj_setup_database -uroot -pdomjudge install-examples diff --git a/.github/jobs/data/gha_ci_bashrc b/.github/jobs/data/gha_ci_bashrc new file mode 100755 index 00000000000..e25db22f3b1 --- /dev/null +++ b/.github/jobs/data/gha_ci_bashrc @@ -0,0 +1,58 @@ +#!/bin/bash + +# Expand aliases for non-interactive shell +shopt -s expand_aliases + +# Fail pipeline when variable is not set or individual command has an non-zero exitcode. +set -euo pipefail + +# Show which commands are being run +set -x + +# Chown the checked out files +sudo chown -R domjudge:domjudge . + +# Shared constants between jobs +export DIR=$(pwd) +export GITSHA=$(git rev-parse HEAD || true) +export PS4='(${BASH_SOURCE}:${LINENO}): - [$?] $ ' export LOGFILE="/opt/domjudge/domserver/webapp/var/log/prod.log" + +# Functions to annotate the Github actions logs +alias trace_on='set -x' +alias trace_off='{ set +x; } 2>/dev/null' + +section_start_internal () { + echo "::group::$1" + trace_on +} + +section_end_internal () { + echo "::endgroup::" + trace_on +} + +alias section_start='trace_off ; section_start_internal ' +alias section_end='trace_off ; section_end_internal ' + +# Shared storage for all artifacts +export ARTIFACTS="$DIR/artifacts" +mkdir -p "$ARTIFACTS" + +function show_phpinfo() { + phpversion=$1 + section_start phpinfo "Show the new PHP info" + update-alternatives --set php /usr/bin/php"${phpversion}" + php -v + php -m + section_end phpinfo +} + +function log_on_err() { + echo -e "\\n\\n=======================================================\\n" + echo "Symfony log:" + if sudo test -f "$LOGFILE" ; then + sudo cat "$LOGFILE" + fi +} + +set -eux diff --git a/.github/jobs/unit-tests.sh b/.github/jobs/unit-tests.sh new file mode 100755 index 00000000000..df549361fc5 --- /dev/null +++ b/.github/jobs/unit-tests.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +git config --global --add safe.directory /__w/domjudge/domjudge + +. .github/jobs/data/gha_ci_bashrc + +section_start current_database_domjudge "Currently installed databases (domjudge)" +set +eu +echo "show databases" | mysql -hsqlserveranother -udomjudge -pdomjudge +echo "show databases" | mysql -hsqlserver -udomjudge -pdomjudge +set -eu +section_end current_database_domjudge + +section_start current_database_root "Currently installed databases (root)" +set +eu +echo "show databases" | mysql -hsqlserver -uroot -pdomjudge +set -eu +section_end current_database_root + +export version=$1 +unittest=$2 +[ "$version" = "8.1" ] && CODECOVERAGE=1 || CODECOVERAGE=0 + +show_phpinfo $version + +.github/jobs/base.sh + +# Add team to admin user +echo "INSERT INTO userrole (userid, roleid) VALUES (1, 3);" | mysql domjudge +echo "UPDATE user SET teamid = 1 WHERE userid = 1;" | mysql domjudge + +# Copy the .env.test file, as this is normally not done during +# installation and we need it. +cp webapp/.env.test /opt/domjudge/domserver/webapp/ + +# We also need the composer.json for PHPunit to detect the correct directory. +cp composer.json /opt/domjudge/domserver/ + +cd /opt/domjudge/domserver + +export APP_ENV="test" + +# Run phpunit tests. +pcov="" +phpcov="" +if [ "$CODECOVERAGE" -eq 1 ]; then + phpcov="-dpcov.enabled=1 -dpcov.directory=webapp/src" + pcov="--coverage-html=${PWD}/coverage-html --coverage-clover coverage.xml" +fi +set +e +php $phpcov lib/vendor/bin/phpunit -c webapp/phpunit.xml.dist webapp/tests/$unittest --log-junit ${DIR}/unit-tests.xml --colors=never $pcov > "$ARTIFACTS"/phpunit.out +UNITSUCCESS=$? +set -e +CNT=0 +if [ $CODECOVERAGE -eq 1 ]; then + CNT=$(sed -n '/Generating code coverage report/,$p' "$ARTIFACTS"/phpunit.out | grep -v DoctrineTestBundle | grep -cv ^$) + FILE=deprecation.txt + sed -n '/Generating code coverage report/,$p' "$ARTIFACTS"/phpunit.out > "$DIR/$FILE" + if [ $CNT -le 12 ]; then + STATE=success + else + STATE=failure + fi + ORIGINAL="gitlab.com/DOMjudge" + REPLACETO="domjudge.gitlab.io/-" + # Copied from CCS + #curl https://api.github.com/repos/domjudge/domjudge/statuses/$CI_COMMIT_SHA \ + # -X POST \ + # -H "Authorization: token $GH_BOT_TOKEN_OBSCURED" \ + # -H "Accept: application/vnd.github.v3+json" \ + # -d "{\"state\": \"$STATE\", \"target_url\": \"${CI_JOB_URL/$ORIGINAL/$REPLACETO}/artifacts/$FILE\", \"description\":\"Symfony deprecations\", \"context\": \"Symfony deprecation\"}" +fi +if [ $UNITSUCCESS -eq 0 ]; then + STATE=success +else + STATE=failure +fi +#curl https://api.github.com/repos/domjudge/domjudge/statuses/$CI_COMMIT_SHA \ +# -X POST \ +# -H "Authorization: token $GH_BOT_TOKEN_OBSCURED" \ +# -H "Accept: application/vnd.github.v3+json" \ +# -d "{\"state\": \"$STATE\", \"target_url\": \"${CI_PIPELINE_URL}/test_report\", \"description\":\"Unit tests\", \"context\": \"unit_tests ($version)\"}" +if [ $UNITSUCCESS -ne 0 ]; then + exit 1 +fi + +if [ $CODECOVERAGE -eq 1 ]; then + section_start uploadcoverage "Upload code coverage" + # Only upload when we got working unit-tests. + set +u # Uses some variables which are not set + # shellcheck disable=SC1090 + . $DIR/.github/jobs/uploadcodecov.sh &>/dev/zero + set -u # Undo set dance + section_end uploadcoverage +fi diff --git a/.github/workflows/check-unit-codecov-update.yml b/.github/workflows/check-unit-codecov-update.yml new file mode 100644 index 00000000000..4ccc26ad4ab --- /dev/null +++ b/.github/workflows/check-unit-codecov-update.yml @@ -0,0 +1,21 @@ +name: Unit tests (Codecov script) +on: + push: + branches: + - main + - '[0-9]+.[0-9]+' + pull_request: + branches: + - main + - '[0-9]+.[0-9]+' + +jobs: + check-static-codecov: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Download latest codecov upload script + run: wget https://codecov.io/bash -O newcodecov + - name: Detect changes to manually verify + run: diff newcodecov .github/jobs/uploadcodecov.sh + diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 9d675a142be..00000000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,95 +0,0 @@ -name: "CodeQL" - -on: - push: - branches: - - main - - '[0-9]+.[0-9]+' - pull_request: - branches: - - main - - '[0-9]+.[0-9]+' - -jobs: - analyze: - # We can not run with our gitlab container - # CodeQL has missing .so files otherwise - name: Analyze - runs-on: ubuntu-latest - env: - COMPILED: "cpp" - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'cpp', 'java', 'javascript', 'python' ] - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - - - name: Install required tools - if: ${{ contains(env.COMPILED, matrix.language) }} - run: | - sudo apt update - sudo apt install -y acl zip unzip apache2 php php-fpm php-gd \ - php-cli php-intl php-mbstring php-mysql php-curl php-json \ - php-xml php-zip ntp make sudo debootstrap \ - libcgroup-dev lsof php-cli php-curl php-json php-xml \ - php-zip procps gcc g++ default-jre-headless \ - default-jdk-headless ghc fp-compiler autoconf automake bats \ - python3-sphinx python3-sphinx-rtd-theme rst2pdf fontconfig \ - python3-yaml latexmk - php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" - HASH="$(wget -q -O - https://composer.github.io/installer.sig)" - php -r "if (hash_file('SHA384', 'composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" - sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer - - - name: Install composer files - if: ${{ contains(env.COMPILED, matrix.language) }} - run: | - composer install --no-scripts - - - name: Configure Makefile - if: ${{ contains(env.COMPILED, matrix.language) }} - run: | - DIR=$(pwd) - mkdir ./installdir - make configure - ./configure --enable-doc-build=no --prefix=$DIR/installdir - - - name: Compile domserver - if: ${{ contains(env.COMPILED, matrix.language) }} - run: | - make domserver - make install-domserver - - - name: Compile the build scripts for languages - run: | - make build-scripts - - - name: Compile judgehost - if: ${{ contains(env.COMPILED, matrix.language) }} - run: | - make judgehost - sudo make install-judgehost - - - name: Remove upstream code - run: | - rm -rf webapp/public/js/ace doc/manual/_static - - - name: Chown everything to the current runner user - if: ${{ contains(env.COMPILED, matrix.language) }} - run: sudo chown -R ${USER} ./installdir - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/shiftleft.yml b/.github/workflows/shiftleft.yml deleted file mode 100644 index 58cfd0a9088..00000000000 --- a/.github/workflows/shiftleft.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: SL Scan - -on: - push: - -jobs: - Scan-Build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Perform Scan - uses: ShiftLeftSecurity/scan-action@master - env: - WORKSPACE: "" - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SCAN_AUTO_BUILD: true - SCAN_ANNOTATE_PR: 0 - with: - output: reports - type: python,bash - - - name: Upload report - uses: github/codeql-action/upload-sarif@v2 - with: - sarif_file: reports diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index c12ad5528d6..33374911d94 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -1,21 +1,58 @@ -name: Unit tests +name: Unit tests CI on: push: - branches: - - main - - '[0-9]+.[0-9]+' + #branches: + # - main + # - '[0-9]+.[0-9]+' pull_request: branches: - main - '[0-9]+.[0-9]+' jobs: - check-static-codecov: + run-unit-tests: runs-on: ubuntu-latest + container: domjudge/gitlabci:2.1 + defaults: + run: + shell: bash + strategy: + matrix: + sqlserver: ['mariadb'] + phpversion: ['8.2'] + testtype: ["Unit"] + #phpversion: ['7.4','8.0','8.1','8.2'] + #testtype: ["Unit","E2E"] + #include: + # - phpversion: "8.1" + # sqlserver: "mysql" + # testtype: "Unit" + # - phpversion: "8.1" + # sqlserver: "mysql" + # testtype: "E2E" + services: + sqlserver: + image: "${{ matrix.sqlserver }}" + env: + #MARIADB_USER: domjudge + #MARIADB_PASSWORD: domjudge + MARIADB_ROOT_PASSWORD: domjudge steps: - uses: actions/checkout@v2 - - name: Download latest codecov upload script - run: wget https://codecov.io/bash -O newcodecov - - name: Detect changes to manually verify - run: diff newcodecov .github/jobs/uploadcodecov.sh + - name: Show current directory + run: pwd + - name: Run gitlab script in altered form + run: .github/jobs/unit-tests.sh "${{ matrix.phpversion }}" "${{ matrix.testtype }}" + - name: Publish Test Results + uses: EnricoMi/publish-unit-test-result-action@v2 + if: always() + with: + files: | + unit-tests.xml + - uses: actions/upload-artifact@v3 + with: + comment_mode: off + name: ci-run-logs-configs + path: | + "artifacts"