@@ -123,6 +123,213 @@ jobs:
123123 name : breakage-${{ matrix.pkg }}-${{ matrix.pkgversion }}
124124 path : breakage/breakage-*
125125
126+ upload :
127+ needs : break
128+ runs-on : ubuntu-latest
129+ steps :
130+ - uses : actions/checkout@v4
131+
132+ - uses : actions/download-artifact@v4
133+ with :
134+ path : breakage
135+ pattern : breakage-*
136+ merge-multiple : true
137+
138+ - run : ls -R
139+ - run : |
140+ cd breakage
141+ echo "| Package name | latest | stable |" > summary.md
142+ echo "|--|--|--|" >> summary.md
143+ count=0
144+ for file in breakage-*
145+ do
146+ if [ $count == "0" ]; then
147+ name=$(echo $file | cut -f2 -d-)
148+ echo -n "| $name | "
149+ else
150+ echo -n "| "
151+ fi
152+ cat $file
153+ if [ $count == "0" ]; then
154+ echo -n " "
155+ count=1
156+ else
157+ echo " |"
158+ count=0
159+ fi
160+ done >> summary.md
161+
162+ - name : Display summary in CI logs
163+ run : |
164+ echo "### Breakage Summary" >> $GITHUB_STEP_SUMMARY
165+ cat breakage/summary.md >> $GITHUB_STEP_SUMMARY
166+
167+ - name : PR comment with file
168+ if : github.event.pull_request.head.repo.fork == false
169+ uses : actions/github-script@main
170+ with :
171+ github-token : ${{ secrets.GITHUB_TOKEN }}
172+ script : |
173+ // Import file content from summary.md
174+ const fs = require('fs')
175+ const filePath = 'breakage/summary.md'
176+ const msg = fs.readFileSync(filePath, 'utf8')
177+
178+ // Get the current PR number from context
179+ const prNumber = context.payload.pull_request.number
180+
181+ // Fetch existing comments on the PR
182+ const { data: comments } = await github.rest.issues.listComments({
183+ owner: context.repo.owner,
184+ repo: context.repo.repo,
185+ issue_number: prNumber
186+ })
187+
188+ // Find a previous comment by the bot to update
189+ const botComment = comments.find(comment => comment.user.id === 41898282)
190+
191+ if (botComment) {
192+ // Update the existing comment
193+ await github.rest.issues.updateComment({
194+ owner: context.repo.owner,
195+ repo: context.repo.repo,
196+ comment_id: botComment.id,
197+ body: msg
198+ })
199+ } else {
200+ // Create a new comment
201+ await github.rest.issues.createComment({
202+ owner: context.repo.owner,
203+ repo: context.repo.repo,
204+ issue_number: prNumber,
205+ body: msg
206+ })
207+ }
208+ # Ref: https://securitylab.github.com/research/github-actions-preventing-pwn-requests
209+ name : Breakage
210+
211+ # read-only repo token
212+ # no access to secrets
213+ on :
214+ pull_request :
215+
216+ jobs :
217+ # Build dynamically the matrix on which the "break" job will run.
218+ # The matrix contains the packages that depend on ${{ env.pkg }}.
219+ # Job "setup_matrix" outputs variable "matrix", which is in turn
220+ # the output of the "getmatrix" step.
221+ # The contents of "matrix" is a JSON description of a matrix used
222+ # in the next step. It has the form
223+ # {
224+ # "pkg": [
225+ # "PROPACK",
226+ # "LLSModels",
227+ # "FletcherPenaltySolver"
228+ # ]
229+ # }
230+ setup_matrix :
231+ runs-on : ubuntu-latest
232+ outputs :
233+ matrix : ${{ steps.getmatrix.outputs.matrix }}
234+ env :
235+ pkg : ${{ github.event.repository.name }}
236+ steps :
237+ - uses : actions/checkout@v4
238+ - uses : julia-actions/setup-julia@v2
239+ with :
240+ version : 1
241+ arch : x64
242+ - id : getmatrix
243+ run : |
244+ julia -e 'using Pkg; Pkg.Registry.add(RegistrySpec(url = "https://github.com/JuliaRegistries/General.git"))'
245+ julia --project=.breakage -e 'using Pkg; Pkg.update(); Pkg.instantiate()'
246+ pkgs=$(julia --project=.breakage .breakage/get_jso_users.jl ${{ env.pkg }})
247+ vs='["latest", "stable"]'
248+ # Check if pkgs is empty, and set it to a JSON array if necessary
249+ if [[ -z "$pkgs" || "$pkgs" == "String[]" ]]; then
250+ echo "No packages found; exiting successfully."
251+ exit 0
252+ fi
253+ vs='["latest", "stable"]'
254+ matrix=$(jq -cn --argjson deps "$pkgs" --argjson vers "$vs" '{pkg: $deps, pkgversion: $vers}') # don't escape quotes like many posts suggest
255+ echo "matrix=$matrix" >> "$GITHUB_OUTPUT"
256+
257+ break :
258+ needs : setup_matrix
259+ if : needs.setup_matrix.result == 'success' && needs.setup_matrix.outputs.matrix != ''
260+ runs-on : ubuntu-latest
261+ strategy :
262+ fail-fast : false
263+ matrix : ${{ fromJSON(needs.setup_matrix.outputs.matrix) }}
264+
265+ steps :
266+ - uses : actions/checkout@v4
267+
268+ # Install Julia
269+ - uses : julia-actions/setup-julia@v2
270+ with :
271+ version : 1
272+ arch : x64
273+ - uses : actions/cache@v4
274+ env :
275+ cache-name : cache-artifacts
276+ with :
277+ path : ~/.julia/artifacts
278+ key : ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
279+ restore-keys : |
280+ ${{ runner.os }}-test-${{ env.cache-name }}-
281+ ${{ runner.os }}-test-
282+ ${{ runner.os }}-
283+ - uses : julia-actions/julia-buildpkg@v1
284+
285+ # Breakage test
286+ - name : ' Breakage of ${{ matrix.pkg }}, ${{ matrix.pkgversion }} version'
287+ env :
288+ PKG : ${{ matrix.pkg }}
289+ VERSION : ${{ matrix.pkgversion }}
290+ run : |
291+ set -v
292+ mkdir -p ./breakage
293+ git clone https://github.com/JuliaSmoothOptimizers/$PKG.jl.git
294+ cd $PKG.jl
295+ if [ $VERSION == "stable" ]; then
296+ TAG=$(git tag -l "v*" --sort=-creatordate | head -n1)
297+ if [ -z "$TAG" ]; then
298+ TAG="no_tag"
299+ else
300+ git checkout $TAG
301+ fi
302+ else
303+ TAG=$VERSION
304+ fi
305+ export TAG
306+ julia -e 'using Pkg;
307+ PKG, TAG, VERSION = ENV["PKG"], ENV["TAG"], ENV["VERSION"]
308+ joburl = joinpath(ENV["GITHUB_SERVER_URL"], ENV["GITHUB_REPOSITORY"], "actions/runs", ENV["GITHUB_RUN_ID"])
309+ open("../breakage/breakage-$PKG-$VERSION", "w") do io
310+ try
311+ TAG == "no_tag" && error("No tag for $VERSION")
312+ pkg"activate .";
313+ pkg"instantiate";
314+ pkg"dev ../";
315+ if TAG == "latest"
316+ global TAG = chomp(read(`git rev-parse --short HEAD`, String))
317+ end
318+ pkg"build";
319+ pkg"test";
320+
321+ print(io, "[]($joburl)");
322+ catch e
323+ @error e;
324+ print(io, "[]($joburl)");
325+ end;
326+ end'
327+
328+ - uses : actions/upload-artifact@v4
329+ with :
330+ name : breakage-${{ matrix.pkg }}-${{ matrix.pkgversion }}
331+ path : breakage/breakage-*
332+
126333 upload :
127334 needs : break
128335 runs-on : ubuntu-latest
0 commit comments