Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .breakage/Project.toml

This file was deleted.

18 changes: 0 additions & 18 deletions .breakage/get_jso_users.jl

This file was deleted.

198 changes: 3 additions & 195 deletions .github/workflows/Breakage.yml
Original file line number Diff line number Diff line change
@@ -1,201 +1,9 @@
# Ref: https://securitylab.github.com/research/github-actions-preventing-pwn-requests
name: Breakage

# read-only repo token
# no access to secrets
on:
pull_request:
types: [opened, synchronize, reopened]

jobs:
# Build dynamically the matrix on which the "break" job will run.
# The matrix contains the packages that depend on ${{ env.pkg }}.
# Job "setup_matrix" outputs variable "matrix", which is in turn
# the output of the "getmatrix" step.
# The contents of "matrix" is a JSON description of a matrix used
# in the next step. It has the form
# {
# "pkg": [
# "PROPACK",
# "LLSModels",
# "FletcherPenaltySolver"
# ]
# }
setup_matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.getmatrix.outputs.matrix }}
env:
pkg: ${{ github.event.repository.name }}
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: 1
arch: x64
- id: getmatrix
run: |
julia -e 'using Pkg; Pkg.Registry.add(RegistrySpec(url = "https://github.com/JuliaRegistries/General.git"))'
julia --project=.breakage -e 'using Pkg; Pkg.update(); Pkg.instantiate()'
pkgs=$(julia --project=.breakage .breakage/get_jso_users.jl ${{ env.pkg }})
vs='["latest", "stable"]'
# Check if pkgs is empty, and set it to a JSON array if necessary
if [[ -z "$pkgs" || "$pkgs" == "String[]" ]]; then
echo "No packages found; exiting successfully."
exit 0
fi
vs='["latest", "stable"]'
matrix=$(jq -cn --argjson deps "$pkgs" --argjson vers "$vs" '{pkg: $deps, pkgversion: $vers}') # don't escape quotes like many posts suggest
echo "matrix=$matrix" >> "$GITHUB_OUTPUT"

break:
needs: setup_matrix
if: needs.setup_matrix.result == 'success' && needs.setup_matrix.outputs.matrix != ''
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.setup_matrix.outputs.matrix) }}

steps:
- uses: actions/checkout@v4

# Install Julia
- uses: julia-actions/setup-julia@v2
with:
version: 1
arch: x64
- uses: actions/cache@v4
env:
cache-name: cache-artifacts
with:
path: ~/.julia/artifacts
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
- uses: julia-actions/julia-buildpkg@v1

# Breakage test
- name: 'Breakage of ${{ matrix.pkg }}, ${{ matrix.pkgversion }} version'
env:
PKG: ${{ matrix.pkg }}
VERSION: ${{ matrix.pkgversion }}
run: |
set -v
mkdir -p ./breakage
git clone https://github.com/JuliaSmoothOptimizers/$PKG.jl.git
cd $PKG.jl
if [ $VERSION == "stable" ]; then
TAG=$(git tag -l "v*" --sort=-creatordate | head -n1)
if [ -z "$TAG" ]; then
TAG="no_tag"
else
git checkout $TAG
fi
else
TAG=$VERSION
fi
export TAG
julia -e 'using Pkg;
PKG, TAG, VERSION = ENV["PKG"], ENV["TAG"], ENV["VERSION"]
joburl = joinpath(ENV["GITHUB_SERVER_URL"], ENV["GITHUB_REPOSITORY"], "actions/runs", ENV["GITHUB_RUN_ID"])
open("../breakage/breakage-$PKG-$VERSION", "w") do io
try
TAG == "no_tag" && error("No tag for $VERSION")
pkg"activate .";
pkg"instantiate";
pkg"dev ../";
if TAG == "latest"
global TAG = chomp(read(`git rev-parse --short HEAD`, String))
end
pkg"build";
pkg"test";

print(io, "[![](https://img.shields.io/badge/$TAG-Pass-green)]($joburl)");
catch e
@error e;
print(io, "[![](https://img.shields.io/badge/$TAG-Fail-red)]($joburl)");
end;
end'

- uses: actions/upload-artifact@v4
with:
name: breakage-${{ matrix.pkg }}-${{ matrix.pkgversion }}
path: breakage/breakage-*

upload:
needs: break
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/download-artifact@v4
with:
path: breakage
pattern: breakage-*
merge-multiple: true

- run: ls -R
- run: |
cd breakage
echo "| Package name | latest | stable |" > summary.md
echo "|--|--|--|" >> summary.md
count=0
for file in breakage-*
do
if [ $count == "0" ]; then
name=$(echo $file | cut -f2 -d-)
echo -n "| $name | "
else
echo -n "| "
fi
cat $file
if [ $count == "0" ]; then
echo -n " "
count=1
else
echo " |"
count=0
fi
done >> summary.md

- name: PR comment with file
uses: actions/github-script@main
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
// Import file content from summary.md
const fs = require('fs')
const filePath = 'breakage/summary.md'
const msg = fs.readFileSync(filePath, 'utf8')

// Get the current PR number from context
const prNumber = context.payload.pull_request.number

// Fetch existing comments on the PR
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber
})

// Find a previous comment by the bot to update
const botComment = comments.find(comment => comment.user.id === 41898282)

if (botComment) {
// Update the existing comment
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: msg
})
} else {
// Create a new comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: msg
})
}
breakage:
uses: JuliaSmoothOptimizers/.github/.github/workflows/Breakage.yml@main
11 changes: 11 additions & 0 deletions .github/workflows/CommentBreakage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: Comment Breakage

on:
workflow_run:
workflows: ["Breakage"]
types:
- completed

Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CommentBreakage triggers a workflow that (presumably) writes a PR comment, but this workflow doesn’t declare any explicit permissions. If the repo’s default GITHUB_TOKEN permission is set to read-only, the reusable workflow won’t be able to create/update PR comments. Add an explicit permissions: block (e.g., issues: write and/or pull-requests: write, plus contents: read if needed) at the workflow level so the called workflow can function reliably while staying least-privilege.

Suggested change
permissions:
contents: read
issues: write
pull-requests: write

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine because we run on workflow_run I think.

jobs:
comment_pr:
uses: JuliaSmoothOptimizers/.github/.github/workflows/CommentBreakage.yml@main
Loading