Skip to content

publish_coverage_pr #294

publish_coverage_pr

publish_coverage_pr #294

#/
# @license Apache-2.0
#
# Copyright (c) 2025 The Stdlib Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#/
# Workflow name:
name: publish_coverage_pr
# Workflow triggers:
on:
workflow_run:
workflows:
- run_tests_coverage_pr
types:
- completed
# Global permissions:
permissions:
# Allow read-only access to the repository contents:
contents: read
# Workflow jobs:
jobs:
# Define a job for publishing coverage results...
publish:
# Define a display name:
name: 'Publish PR coverage results'
# Only run if the triggering workflow succeeded:
if: github.event.workflow_run.conclusion == 'success'
# Define the type of virtual host machine:
runs-on: ubuntu-latest
# Define the sequence of job steps...
steps:
# Download PR metadata artifact:
- name: 'Download PR metadata'
id: download-metadata
# Pin action to full length commit SHA
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: pr-metadata
path: pr-metadata/
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true
# Read PR metadata:
- name: 'Read PR metadata'
id: pr-metadata
if: steps.download-metadata.outcome == 'success'
run: |
pr_number=$(cat pr-metadata/pr_number)
echo "pr_number=$pr_number" >> $GITHUB_OUTPUT
{
echo 'report<<EOF'
cat pr-metadata/report
echo 'EOF'
} >> $GITHUB_OUTPUT
# Post report as comment to PR:
- name: 'Post report as comment to PR'
if: steps.download-metadata.outcome == 'success'
# Pin action to full length commit SHA
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
github-token: ${{ secrets.STDLIB_BOT_PAT_REPO_WRITE }}
script: |
const prNumber = parseInt('${{ steps.pr-metadata.outputs.pr_number }}');
const { data: comments } = await github.rest.issues.listComments({
'issue_number': prNumber,
'owner': context.repo.owner,
'repo': context.repo.repo,
});
const botComment = comments.find( comment => comment.user.login === 'stdlib-bot' && comment.body.includes( '## Coverage Report' ) );
if ( botComment ) {
await github.rest.issues.updateComment({
'owner': context.repo.owner,
'repo': context.repo.repo,
'comment_id': botComment.id,
'body': `${{ steps.pr-metadata.outputs.report }}`
});
} else {
await github.rest.issues.createComment({
'issue_number': prNumber,
'owner': context.repo.owner,
'repo': context.repo.repo,
'body': `${{ steps.pr-metadata.outputs.report }}`
});
}
# Download coverage artifacts:
- name: 'Download coverage artifacts'
id: download-coverage
# Pin action to full length commit SHA
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: coverage-artifacts
path: artifacts/
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true
# Checkout coverage repository:
- name: 'Checkout coverage repository'
if: steps.download-coverage.outcome == 'success'
# Pin action to full length commit SHA
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
# Code coverage repository:
repository: 'stdlib-js/www-test-code-coverage'
# File path to checkout to:
path: './www-test-code-coverage'
# Specify whether to remove untracked files before checking out the repository:
clean: false
# Limit clone depth to the most recent commit:
fetch-depth: 1
# Token for accessing the repository:
token: ${{ secrets.STDLIB_BOT_FGPAT_REPO_READ }}
# Avoid storing GitHub token in local Git configuration:
persist-credentials: false
# Checkout coverage repository branch for PR:
- name: 'Checkout coverage repository branch'
if: steps.download-coverage.outcome == 'success'
run: |
cd ./www-test-code-coverage
BRANCH_NAME="pr-${{ steps.pr-metadata.outputs.pr_number }}"
git fetch origin $BRANCH_NAME || true
git checkout $BRANCH_NAME || git checkout -b $BRANCH_NAME
# Remove all directories except .github and .git from branch:
find . -mindepth 1 -maxdepth 1 -type d -not -name '.github' -not -name '.git' -exec git rm -rf {} + || true
# Copy artifacts to the repository:
- name: 'Copy artifacts to the repository'
if: steps.download-coverage.outcome == 'success'
run: |
if [ -d "./artifacts" ]; then
cp -R ./artifacts/* ./www-test-code-coverage
# Get commit SHA and timestamp from the workflow run:
commit_sha="${{ github.event.workflow_run.head_sha }}"
commit_timestamp=$(date -u +"%Y-%m-%d %H:%M:%S")
# Append coverage to ndjson files:
files=$(find ./artifacts -name 'index.html')
for file in $files; do
file=${file//artifacts/www-test-code-coverage}
coverage=$(echo -n '['; grep -oP "(?<=class='fraction'>)[0-9]+/[0-9]+" $file | awk -F/ '{ if ($2 != 0) print $1 "," $2 "," ($1/$2)*100; else print $1 "," $2 ",100" }' | tr '\n' ',' | sed 's/,$//'; echo -n ",\"$commit_sha\",\"$commit_timestamp\"]")
echo $coverage >> $(dirname $file)/coverage.ndjson
done
else
echo "The artifacts directory does not exist."
fi
# Import GPG key to sign commits:
- name: 'Import GPG key to sign commits'
if: steps.download-coverage.outcome == 'success'
# Pin action to full length commit SHA
uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0
with:
gpg_private_key: ${{ secrets.STDLIB_BOT_GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.STDLIB_BOT_GPG_PASSPHRASE }}
git_user_signingkey: true
git_commit_gpgsign: true
workdir: ./www-test-code-coverage
# Commit and push changes:
- name: 'Commit and push changes'
if: steps.download-coverage.outcome == 'success'
env:
REPO_GITHUB_TOKEN: ${{ secrets.STDLIB_BOT_PAT_REPO_WRITE }}
USER_NAME: stdlib-bot
run: |
cd ./www-test-code-coverage
BRANCH_NAME="pr-${{ steps.pr-metadata.outputs.pr_number }}"
git config --local user.email "[email protected]"
git config --local user.name "stdlib-bot"
git add .
git commit -m "Update artifacts" || exit 0
git push "https://$USER_NAME:[email protected]/stdlib-js/www-test-code-coverage.git" $BRANCH_NAME