name: Report backend memory on: workflow_run: types: [completed] workflows: - Get backend memory usage # get-backend-memory.yml jobs: compare-memory: runs-on: ubuntu-latest if: ${{ github.event.workflow_run.conclusion == 'success' }} permissions: pull-requests: write steps: - name: Download artifact uses: actions/github-script@v8.0.0 with: script: | const fs = require('fs'); let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ owner: context.repo.owner, repo: context.repo.repo, run_id: context.payload.workflow_run.id, }); let matchArtifacts = allArtifacts.data.artifacts.filter((artifact) => { return artifact.name.startsWith("memory-artifact-") || artifact.name == "memory-artifact" }); await Promise.all(matchArtifacts.map(async (artifact) => { let download = await github.rest.actions.downloadArtifact({ owner: context.repo.owner, repo: context.repo.repo, artifact_id: artifact.id, archive_format: 'zip', }); await fs.promises.writeFile(`${process.env.GITHUB_WORKSPACE}/${artifact.name}.zip`, Buffer.from(download.data)); })); - name: Extract all artifacts run: | find . -mindepth 1 -maxdepth 1 -type f -name '*.zip' -exec unzip {} -d artifacts ';' ls -la artifacts/ - name: Load PR Number id: load-pr-num run: echo "pr-number=$(cat artifacts/pr_number)" >> "$GITHUB_OUTPUT" - name: Output base run: cat ./artifacts/memory-base.json - name: Output head run: cat ./artifacts/memory-head.json - name: Compare memory usage id: compare run: | BASE_MEMORY=$(cat ./artifacts/memory-base.json) HEAD_MEMORY=$(cat ./artifacts/memory-head.json) variation() { calc() { BASE=$(echo "$BASE_MEMORY" | jq -r ".${1}.${2} // 0") HEAD=$(echo "$HEAD_MEMORY" | jq -r ".${1}.${2} // 0") DIFF=$((HEAD - BASE)) if [ "$BASE" -gt 0 ]; then DIFF_PERCENT=$(echo "scale=2; ($DIFF * 100) / $BASE" | bc) else DIFF_PERCENT=0 fi # Convert KB to MB for readability BASE_MB=$(echo "scale=2; $BASE / 1024" | bc) HEAD_MB=$(echo "scale=2; $HEAD / 1024" | bc) DIFF_MB=$(echo "scale=2; $DIFF / 1024" | bc) JSON=$(jq -c -n \ --argjson base "$BASE_MB" \ --argjson head "$HEAD_MB" \ --argjson diff "$DIFF_MB" \ --argjson diff_percent "$DIFF_PERCENT" \ '{base: $base, head: $head, diff: $diff, diff_percent: $diff_percent}') echo "$JSON" } JSON=$(jq -c -n \ --argjson VmRSS "$(calc $1 VmRSS)" \ --argjson VmHWM "$(calc $1 VmHWM)" \ --argjson VmSize "$(calc $1 VmSize)" \ '{VmRSS: $VmRSS, VmHWM: $VmHWM, VmSize: $VmSize}') echo "$JSON" } JSON=$(jq -c -n \ --argjson beforeGc "$(variation beforeGc)" \ --argjson afterGc "$(variation afterGc)" \ '{beforeGc: $beforeGc, afterGc: $afterGc}') echo "res=$JSON" >> "$GITHUB_OUTPUT" - id: build-comment name: Build memory comment run: | HEADER="## Backend memory usage comparison" FOOTER="[See workflow logs for details](https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})" echo "$HEADER" > ./output.md echo >> ./output.md table() { line() { BASE=$(echo "${{ steps.compare.outputs.res }}" | jq -r ".${1}.${2}.base") HEAD=$(echo "${{ steps.compare.outputs.res }}" | jq -r ".${1}.${2}.head") DIFF=$(echo "${{ steps.compare.outputs.res }}" | jq -r ".${1}.${2}.diff") DIFF_PERCENT=$(echo "${{ steps.compare.outputs.res }}" | jq -r ".${1}.${2}.diff_percent") echo "| ${2} | ${BASE} MB | ${HEAD} MB | ${DIFF} MB (${DIFF_PERCENT}%) |" >> ./output.md } echo "| Metric | base | head | Diff |" >> ./output.md echo "|--------|------|------|------|" >> ./output.md line $1 VmRSS line $1 VmHWM line $1 VmSize } echo "### Before GC" >> ./output.md table beforeGc echo >> ./output.md echo "### After GC" >> ./output.md table afterGc echo >> ./output.md # Determine if this is a significant change (more than 5% increase) if [ "$(echo "${{ steps.compare.outputs.res }}" | jq -r '.afterGc.VmRSS.diff_percent | tonumber > 5')" = "true" ]; then echo "⚠️ **Warning**: Memory usage has increased by more than 5%. Please verify this is not an unintended change." >> ./output.md echo >> ./output.md fi echo "$FOOTER" >> ./output.md - uses: thollander/actions-comment-pull-request@v3 with: pr-number: ${{ steps.load-pr-num.outputs.pr-number }} comment-tag: show_memory_diff file-path: ./output.md - name: Tell error to PR uses: thollander/actions-comment-pull-request@v3 if: failure() && steps.load-pr-num.outputs.pr-number with: pr-number: ${{ steps.load-pr-num.outputs.pr-number }} comment-tag: show_memory_diff_error message: | An error occurred while comparing backend memory usage. See [workflow logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.