From 5e70fd7a2e16627c61bdcbf2347c562aa4624f6b Mon Sep 17 00:00:00 2001 From: Tangi Migot Date: Mon, 14 Oct 2024 09:27:34 -0400 Subject: [PATCH] Add template folder (#2) --- template/.breakage/Project.toml | 3 + template/.breakage/get_jso_users.jl | 18 ++ template/.github/workflows/Breakage.yml | 157 ++++++++++++++++++ ...nchmarkCI %}Benchmark.yml{% endif %}.jinja | 38 +++++ ...dBenchmark %}Project.toml{% endif %}.jinja | 2 + ...Benchmark %}benchmarks.jl{% endif %}.jinja | 14 ++ 6 files changed, 232 insertions(+) create mode 100644 template/.breakage/Project.toml create mode 100644 template/.breakage/get_jso_users.jl create mode 100644 template/.github/workflows/Breakage.yml create mode 100644 template/.github/workflows/{% if AddBenchmarkCI %}Benchmark.yml{% endif %}.jinja create mode 100644 template/{% if AddBenchmark %}benchmark{% endif %}.jinja/{% if AddBenchmark %}Project.toml{% endif %}.jinja create mode 100644 template/{% if AddBenchmark %}benchmark{% endif %}.jinja/{% if AddBenchmark %}benchmarks.jl{% endif %}.jinja diff --git a/template/.breakage/Project.toml b/template/.breakage/Project.toml new file mode 100644 index 0000000..7f17b55 --- /dev/null +++ b/template/.breakage/Project.toml @@ -0,0 +1,3 @@ +[deps] +GitHub = "bc5e4493-9b4d-5f90-b8aa-2b2bcaad7a26" +PkgDeps = "839e9fc8-855b-5b3c-a3b7-2833d3dd1f59" diff --git a/template/.breakage/get_jso_users.jl b/template/.breakage/get_jso_users.jl new file mode 100644 index 0000000..0d87f55 --- /dev/null +++ b/template/.breakage/get_jso_users.jl @@ -0,0 +1,18 @@ +import GitHub, PkgDeps # both export users() + +length(ARGS) >= 1 || error("specify at least one JSO package as argument") + +jso_repos, _ = GitHub.repos("JuliaSmoothOptimizers") +jso_names = [splitext(x.name)[1] for x ∈ jso_repos] + +name = splitext(ARGS[1])[1] +name ∈ jso_names || error("argument should be one of ", jso_names) + +dependents = String[] +try + global dependents = filter(x -> x ∈ jso_names, PkgDeps.users(name)) +catch e + # package not registered; don't insert into dependents +end + +println(dependents) diff --git a/template/.github/workflows/Breakage.yml b/template/.github/workflows/Breakage.yml new file mode 100644 index 0000000..96f0ea6 --- /dev/null +++ b/template/.github/workflows/Breakage.yml @@ -0,0 +1,157 @@ +# Ref: https://securitylab.github.com/research/github-actions-preventing-pwn-requests +name: Breakage + +# read-only repo token +# no access to secrets +on: + pull_request: + +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"]' + 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 + 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("Not 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: thollander/actions-comment-pull-request@v2 + with: + filePath: breakage/summary.md diff --git a/template/.github/workflows/{% if AddBenchmarkCI %}Benchmark.yml{% endif %}.jinja b/template/.github/workflows/{% if AddBenchmarkCI %}Benchmark.yml{% endif %}.jinja new file mode 100644 index 0000000..2edfe4e --- /dev/null +++ b/template/.github/workflows/{% if AddBenchmarkCI %}Benchmark.yml{% endif %}.jinja @@ -0,0 +1,38 @@ +name: Run benchmarks + +on: + pull_request: + paths: + - "src/**" + - "benchmark/**" + - "Project.toml" + - "benchmark/Project.toml" + +permissions: + contents: write + issues: write + pull-requests: write + +concurrency: + # Skip intermediate builds: always. + # Cancel intermediate builds: only if it is a pull request build. + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} + +jobs: + benchmark: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@latest + with: + version: 1 + - uses: julia-actions/julia-buildpkg@latest + - name: Install dependencies + run: julia -e 'using Pkg; pkg"add PkgBenchmark BenchmarkCI@0.1"' + - name: Run benchmarks + run: julia -e 'using BenchmarkCI; BenchmarkCI.judge(baseline="origin/main")' + - name: Post results + run: julia -e 'using BenchmarkCI; BenchmarkCI.postjudge()' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/template/{% if AddBenchmark %}benchmark{% endif %}.jinja/{% if AddBenchmark %}Project.toml{% endif %}.jinja b/template/{% if AddBenchmark %}benchmark{% endif %}.jinja/{% if AddBenchmark %}Project.toml{% endif %}.jinja new file mode 100644 index 0000000..05a4894 --- /dev/null +++ b/template/{% if AddBenchmark %}benchmark{% endif %}.jinja/{% if AddBenchmark %}Project.toml{% endif %}.jinja @@ -0,0 +1,2 @@ +[deps] +BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" diff --git a/template/{% if AddBenchmark %}benchmark{% endif %}.jinja/{% if AddBenchmark %}benchmarks.jl{% endif %}.jinja b/template/{% if AddBenchmark %}benchmark{% endif %}.jinja/{% if AddBenchmark %}benchmarks.jl{% endif %}.jinja new file mode 100644 index 0000000..7d3c9e8 --- /dev/null +++ b/template/{% if AddBenchmark %}benchmark{% endif %}.jinja/{% if AddBenchmark %}benchmarks.jl{% endif %}.jinja @@ -0,0 +1,14 @@ +using BenchmarkTools, ADNLPModels +using JSOSuite + +# Run locally with `tune!(SUITE)` and then `run(SUITE)` +const SUITE = BenchmarkGroup() + +SUITE["solvers"] = BenchmarkGroup(["solver"]) + +nlp = ADNLPModel(x -> (x[1] - 1)^2 + 4 * (x[2] - x[1]^2)^2, [-1.2; 1.0]) +for solver in eachrow(JSOSuite.select_optimizers(nlp)) + SUITE["solvers"][solver.name] = @benchmarkable begin + minimize($(solver.name), $nlp) + end +end