# Listens for new PR comments containing !pp check [id], and runs a diffcalc comparison against master. # Usage: # !pp check 0 | Runs only the osu! ruleset. # !pp check 0 2 | Runs only the osu! and catch rulesets. # name: Difficulty Calculation on: issue_comment: types: [ created ] env: CONCURRENCY: 4 ALLOW_DOWNLOAD: 1 SAVE_DOWNLOADED: 1 SKIP_INSERT_ATTRIBUTES: 1 jobs: metadata: name: Check for requests runs-on: self-hosted if: github.event.issue.pull_request && contains(github.event.comment.body, '!pp check') && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') outputs: matrix: ${{ steps.generate-matrix.outputs.matrix }} continue: ${{ steps.generate-matrix.outputs.continue }} steps: - name: Construct build matrix id: generate-matrix run: | if [[ "${{ github.event.comment.body }}" =~ "osu" ]] ; then MATRIX_PROJECTS_JSON+='{ "name": "osu", "id": 0 },' fi if [[ "${{ github.event.comment.body }}" =~ "taiko" ]] ; then MATRIX_PROJECTS_JSON+='{ "name": "taiko", "id": 1 },' fi if [[ "${{ github.event.comment.body }}" =~ "catch" ]] ; then MATRIX_PROJECTS_JSON+='{ "name": "catch", "id": 2 },' fi if [[ "${{ github.event.comment.body }}" =~ "mania" ]] ; then MATRIX_PROJECTS_JSON+='{ "name": "mania", "id": 3 },' fi if [[ "${MATRIX_PROJECTS_JSON}" != "" ]]; then MATRIX_JSON="{ \"ruleset\": [ ${MATRIX_PROJECTS_JSON} ] }" echo "${MATRIX_JSON}" CONTINUE="yes" else CONTINUE="no" fi echo "::set-output name=continue::${CONTINUE}" echo "::set-output name=matrix::${MATRIX_JSON}" diffcalc: name: Run runs-on: self-hosted if: needs.metadata.outputs.continue == 'yes' needs: metadata strategy: matrix: ${{ fromJson(needs.metadata.outputs.matrix) }} steps: - name: Verify MySQL connection from host run: | mysql -e "SHOW DATABASES" - name: Drop previous databases run: | for db in osu_master osu_pr do mysql -e "DROP DATABASE IF EXISTS $db" done - name: Create directory structure run: | mkdir -p $GITHUB_WORKSPACE/master/ mkdir -p $GITHUB_WORKSPACE/pr/ - name: Get upstream branch # https://akaimo.hatenablog.jp/entry/2020/05/16/101251 id: upstreambranch env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | echo "::set-output name=branchname::$(curl -H "Authorization: token ${GITHUB_TOKEN}" ${{ github.event.issue.pull_request.url }} | jq '.head.ref' | sed 's/\"//g')" echo "::set-output name=repo::$(curl -H "Authorization: token ${GITHUB_TOKEN}" ${{ github.event.issue.pull_request.url }} | jq '.head.repo.full_name' | sed 's/\"//g')" # Checkout osu - name: Checkout osu (master) uses: actions/checkout@v2 with: path: 'master/osu' - name: Checkout osu (pr) uses: actions/checkout@v2 with: path: 'pr/osu' repository: ${{ steps.upstreambranch.outputs.repo }} ref: ${{ steps.upstreambranch.outputs.branchname }} - name: Checkout osu-difficulty-calculator (master) uses: actions/checkout@v2 with: repository: ppy/osu-difficulty-calculator path: 'master/osu-difficulty-calculator' - name: Checkout osu-difficulty-calculator (pr) uses: actions/checkout@v2 with: repository: ppy/osu-difficulty-calculator path: 'pr/osu-difficulty-calculator' - name: Install .NET 5.0.x uses: actions/setup-dotnet@v1 with: dotnet-version: "5.0.x" # Sanity checks to make sure diffcalc is not run when incompatible. - name: Build diffcalc (master) run: | cd $GITHUB_WORKSPACE/master/osu-difficulty-calculator ./UseLocalOsu.sh dotnet build - name: Build diffcalc (pr) run: | cd $GITHUB_WORKSPACE/pr/osu-difficulty-calculator ./UseLocalOsu.sh dotnet build - name: Download + import data run: | PERFORMANCE_DATA_NAME=$(curl https://data.ppy.sh/ | grep performance_${{ matrix.ruleset.name }}_top_1000 | tail -1 | awk -F "\"" '{print $2}' | sed 's/\.tar\.bz2//g') BEATMAPS_DATA_NAME=$(curl https://data.ppy.sh/ | grep osu_files | tail -1 | awk -F "\"" '{print $2}' | sed 's/\.tar\.bz2//g') # Set env variable for further steps. echo "BEATMAPS_PATH=$GITHUB_WORKSPACE/$BEATMAPS_DATA_NAME" >> $GITHUB_ENV cd $GITHUB_WORKSPACE echo "Downloading database dump $PERFORMANCE_DATA_NAME.." wget -q -nc https://data.ppy.sh/$PERFORMANCE_DATA_NAME.tar.bz2 echo "Extracting.." tar -xf $PERFORMANCE_DATA_NAME.tar.bz2 echo "Downloading beatmap dump $BEATMAPS_DATA_NAME.." wget -q -nc https://data.ppy.sh/$BEATMAPS_DATA_NAME.tar.bz2 echo "Extracting.." tar -xf $BEATMAPS_DATA_NAME.tar.bz2 cd $PERFORMANCE_DATA_NAME for db in osu_master osu_pr do echo "Setting up database $db.." mysql -e "CREATE DATABASE $db" echo "Importing beatmaps.." cat osu_beatmaps.sql | mysql $db echo "Importing beatmapsets.." cat osu_beatmapsets.sql | mysql $db echo "Creating table structure.." mysql $db -e 'CREATE TABLE `osu_beatmap_difficulty` ( `beatmap_id` int unsigned NOT NULL, `mode` tinyint NOT NULL DEFAULT 0, `mods` int unsigned NOT NULL, `diff_unified` float NOT NULL, `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`beatmap_id`,`mode`,`mods`), KEY `diff_sort` (`mode`,`mods`,`diff_unified`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;' done - name: Run diffcalc (master) env: DB_NAME: osu_master run: | cd $GITHUB_WORKSPACE/master/osu-difficulty-calculator/osu.Server.DifficultyCalculator dotnet run -c:Release -- all -m ${{ matrix.ruleset.id }} -ac -c ${{ env.CONCURRENCY }} - name: Run diffcalc (pr) env: DB_NAME: osu_pr run: | cd $GITHUB_WORKSPACE/pr/osu-difficulty-calculator/osu.Server.DifficultyCalculator dotnet run -c:Release -- all -m ${{ matrix.ruleset.id }} -ac -c ${{ env.CONCURRENCY }} - name: Print diffs run: | mysql -e " SELECT m.beatmap_id, m.mods, b.filename, m.diff_unified as 'sr_master', p.diff_unified as 'sr_pr', (p.diff_unified - m.diff_unified) as 'diff' FROM osu_master.osu_beatmap_difficulty m JOIN osu_pr.osu_beatmap_difficulty p ON m.beatmap_id = p.beatmap_id AND m.mode = p.mode AND m.mods = p.mods JOIN osu_pr.osu_beatmaps b ON b.beatmap_id = p.beatmap_id WHERE abs(m.diff_unified - p.diff_unified) > 0.1 ORDER BY abs(m.diff_unified - p.diff_unified) DESC LIMIT 10000;" # Todo: Run ppcalc