diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 67f3220..5a66efc 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1,7 +1,48 @@ name: CI on: - - pull_request + pull_request: + branches: + - main + - dev + paths-ignore: + - "docs/**" + push: + branches: + - main + paths-ignore: + - "docs/**" jobs: + formatter: + runs-on: ${{ matrix.os }} + strategy: + matrix: + julia-version: [1] + julia-arch: [x86] + os: [ubuntu-latest] + steps: + - uses: julia-actions/setup-julia@latest + with: + version: ${{ matrix.julia-version }} + + - uses: actions/checkout@v4 + - name: Install JuliaFormatter and format + # This will use the latest version by default but you can set the version like so: + # + # julia -e 'using Pkg; Pkg.add(PackageSpec(name="JuliaFormatter", version="0.13.0"))' + run: | + julia -e 'using Pkg; Pkg.add(PackageSpec(name="JuliaFormatter", version="1.0.50"))' + julia -e 'using JuliaFormatter; format(".", verbose=true)' + - name: Format check + run: | + julia -e ' + out = Cmd(`git diff`) |> read |> String + if out == "" + exit(0) + else + @error "Some files have not been formatted !!!" + write(stdout, out) + exit(1) + end' test: name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} runs-on: ${{ matrix.os }} @@ -10,28 +51,33 @@ jobs: matrix: version: - "1.9" - - 'nightly' + - "1" # automatically expands to the latest stable 1.x release of Julia + - "pre" os: - ubuntu-latest - - macOS-latest - - windows-latest + threads: + - "2" arch: - x64 - x86 - threads: - - "2" - exclude: + include: + # test macOS and Windows with latest Julia only - os: macOS-latest - arch: x86 + arch: x64 + version: 1 + - os: windows-latest + arch: x64 + version: 1 - os: windows-latest arch: x86 + version: 1 steps: - - uses: actions/checkout@v2 - - uses: julia-actions/setup-julia@v1 + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 with: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - - uses: actions/cache@v1 + - uses: actions/cache@v4 env: cache-name: cache-artifacts with: @@ -46,29 +92,29 @@ jobs: env: JULIA_NUM_THREADS: ${{ matrix.threads }} - uses: julia-actions/julia-processcoverage@v1 - - uses: codecov/codecov-action@v1 + - uses: codecov/codecov-action@v4 with: file: lcov.info - docs: - name: Documentation - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: julia-actions/setup-julia@v1 - with: - version: "1" - - run: | - julia --project=docs -e ' - using Pkg - Pkg.develop(PackageSpec(path=pwd())) - Pkg.instantiate()' - - run: | - julia --project=docs -e ' - using Documenter: DocMeta, doctest - using CBLS - DocMeta.setdocmeta!(CBLS, :DocTestSetup, :(using CBLS); recursive=true) - doctest(CBLS)' - - run: julia --project=docs docs/make.jl - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} + # docs: + # name: Documentation + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + # - uses: julia-actions/setup-julia@v1 + # with: + # version: "1" + # - run: | + # julia --project=docs -e ' + # using Pkg + # Pkg.develop(PackageSpec(path=pwd())) + # Pkg.instantiate()' + # - run: | + # julia --project=docs -e ' + # using Documenter: DocMeta, doctest + # using Constraints + # DocMeta.setdocmeta!(Constraints, :DocTestSetup, :(using Constraints); recursive=true) + # doctest(Constraints)' + # - run: julia --project=docs docs/make.jl + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml index cba9134..f889647 100644 --- a/.github/workflows/CompatHelper.yml +++ b/.github/workflows/CompatHelper.yml @@ -1,16 +1,43 @@ -name: CompatHelper on: schedule: - cron: 0 0 * * * workflow_dispatch: +permissions: + contents: write + pull-requests: write jobs: CompatHelper: runs-on: ubuntu-latest steps: - - name: Pkg.add("CompatHelper") - run: julia -e 'using Pkg; Pkg.add("CompatHelper")' - - name: CompatHelper.main() + - name: Check if Julia is already available in the PATH + id: julia_in_path + run: which julia + continue-on-error: true + - name: Install Julia, but only if it is not already available in the PATH + uses: julia-actions/setup-julia@v2 + with: + version: "1" + arch: ${{ runner.arch }} + if: steps.julia_in_path.outcome != 'success' + - name: "Add the General registry via Git" + run: | + import Pkg + ENV["JULIA_PKG_SERVER"] = "" + Pkg.Registry.add("General") + shell: julia --color=yes {0} + - name: "Install CompatHelper" + run: | + import Pkg + name = "CompatHelper" + uuid = "aa819f21-2bde-4658-8897-bab36330d9b7" + version = "3" + Pkg.add(; name, uuid, version) + shell: julia --color=yes {0} + - name: "Run CompatHelper" + run: | + import CompatHelper + CompatHelper.main() + shell: julia --color=yes {0} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }} - run: julia -e 'using CompatHelper; CompatHelper.main()' diff --git a/.github/workflows/SpellCheck.yml b/.github/workflows/SpellCheck.yml new file mode 100644 index 0000000..ed4fe17 --- /dev/null +++ b/.github/workflows/SpellCheck.yml @@ -0,0 +1,13 @@ +name: Spell Check + +on: [pull_request] + +jobs: + typos-check: + name: Spell Check with Typos + runs-on: ubuntu-latest + steps: + - name: Checkout Actions Repository + uses: actions/checkout@v4 + - name: Check spelling + uses: crate-ci/typos@v1.18.0 diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml index f49313b..0cd3114 100644 --- a/.github/workflows/TagBot.yml +++ b/.github/workflows/TagBot.yml @@ -4,6 +4,22 @@ on: types: - created workflow_dispatch: + inputs: + lookback: + default: "3" +permissions: + actions: read + checks: read + contents: write + deployments: read + issues: read + discussions: read + packages: read + pages: read + pull-requests: read + repository-projects: read + security-events: read + statuses: read jobs: TagBot: if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' diff --git a/.github/workflows/register.yml b/.github/workflows/register.yml new file mode 100644 index 0000000..5b7cd3b --- /dev/null +++ b/.github/workflows/register.yml @@ -0,0 +1,16 @@ +name: Register Package +on: + workflow_dispatch: + inputs: + version: + description: Version to register or component to bump + required: true +jobs: + register: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: julia-actions/RegisterAction@latest + with: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/Project.toml b/Project.toml index 72db1d4..2a0a163 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "CBLS" uuid = "a3809bfe-37bb-4d48-a667-bac4c6be8d90" authors = ["Jean-Francois Baffier"] -version = "0.2.1" +version = "0.2.2" [deps] ConstraintCommons = "e37357d9-0691-492f-a822-e5ea6a920954" @@ -24,8 +24,9 @@ JuMP = "1" Lazy = "0.15" LocalSearchSolvers = "0.4" MathOptInterface = "1" -TestItems = "0.1" -julia = "1.6" +Pkg = "1" +TestItems = "0.1, 1" +julia = "1.9" [extras] Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" diff --git a/src/CBLS.jl b/src/CBLS.jl index 2895f26..1cca870 100644 --- a/src/CBLS.jl +++ b/src/CBLS.jl @@ -49,7 +49,7 @@ export Maximum export MDDConstraint export Minimum export NValues -export NoOverlap, NoOverlapNoZero, NoOverlapWithZero +export NoOverlap#, NoOverlapNoZero, NoOverlapWithZero export Ordered export Regular export Sum diff --git a/src/attributes.jl b/src/attributes.jl index 12490d3..10dca07 100644 --- a/src/attributes.jl +++ b/src/attributes.jl @@ -24,10 +24,19 @@ MOI.set(model::Optimizer, p::MOI.RawOptimizerAttribute, value) = set_option!( model, p.name, value) MOI.get(model::Optimizer, p::MOI.RawOptimizerAttribute) = get_option(model, p.name) -function MOI.set(model::Optimizer, ::MOI.NumberOfThreads, value) - set_option!(model, "threads", isnothing(value) ? typemax(0) : value) +function MOI.set(model::Optimizer, ::MOI.NumberOfThreads, value::Int) + set_option!(model, "threads", value) end +function MOI.set( + model::Optimizer, ::MOI.NumberOfThreads, value::Union{AbstractVector, AbstractDict}) + set_option!(model, "process_threads_map", value) +end + function MOI.get(model::Optimizer, ::MOI.NumberOfThreads) - nt = get_option(model, "threads") - return nt == typemax(0) ? nothing : nt + ptm = get_option(model, "process_threads_map") + if length(ptm) == 0 || (haskey(ptm, 1) && length(ptm) == 1) + nt = get_option(model, "threads") + return nt == typemax(0) ? nothing : nt + end + return ptm end diff --git a/src/constraints/intention.jl b/src/constraints/intention.jl index 65a5c44..bf6788b 100644 --- a/src/constraints/intention.jl +++ b/src/constraints/intention.jl @@ -1,4 +1,4 @@ -# Intention constraints emcompass any generic constraint. DistDifferent is implemented as an example of an intensional constraint. +# Intention constraints encompass any generic constraint. DistDifferent is implemented as an example of an intensional constraint. """ MOIDistDifferent <: MOI.AbstractVectorSet diff --git a/test/Aqua.jl b/test/Aqua.jl new file mode 100644 index 0000000..5f172c8 --- /dev/null +++ b/test/Aqua.jl @@ -0,0 +1,37 @@ +@testset "Aqua.jl" begin + import Aqua + import CBLS + import JuMP + import MathOptInterface + + # TODO: Fix the broken tests and remove the `broken = true` flag + Aqua.test_all( + CBLS; + ambiguities = (broken = true,), + deps_compat = false, + piracies = (broken = true,), + unbound_args = (broken = false) + ) + + @testset "Ambiguities: CBLS" begin + # Aqua.test_ambiguities(CBLS;) + end + + @testset "Piracies: CBLS" begin + Aqua.test_piracies(CBLS; + # Check with JuMP-dev + treat_as_own = [JuMP.build_variable, Base.copy, MathOptInterface.empty!] + ) + end + + @testset "Dependencies compatibility (no extras)" begin + Aqua.test_deps_compat( + CBLS; + check_extras = false # ignore = [:Random] + ) + end + + @testset "Unbound type parameters" begin + # Aqua.test_unbound_args(CBLS;) + end +end diff --git a/test/JuMP.jl b/test/JuMP.jl index 8707bcd..dc22b2b 100644 --- a/test/JuMP.jl +++ b/test/JuMP.jl @@ -21,6 +21,11 @@ end @test get_optimizer_attribute(model, "iteration") == 100 set_time_limit_sec(model, 5.0) @test time_limit_sec(model) == 5.0 + set_optimizer_attribute(model, "threads", 2) + @test get_optimizer_attribute(model, "threads") == 2 + T = Dict(2 => 3, 3 => 1) + set_optimizer_attribute(model, "process_threads_map", T) + @test get_optimizer_attribute(model, "process_threads_map") == T @variable(model, 0≤x≤20, Int) @variable(model, y in DiscreteSet(0:20)) diff --git a/test/MOI_wrapper.jl b/test/MOI_wrapper.jl index 7f4a6d7..d20863f 100644 --- a/test/MOI_wrapper.jl +++ b/test/MOI_wrapper.jl @@ -79,5 +79,5 @@ end end # module TestCBLS -# This line at tne end of the file runs all the tests! +# This line at the end of the file runs all the tests! TestCBLS.runtests() diff --git a/test/runtests.jl b/test/runtests.jl index 8fb5049..98d3020 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -2,6 +2,7 @@ using CBLS using Test @testset "CBLS.jl" begin + include("Aqua.jl") include("MOI_wrapper.jl") include("JuMP.jl") include("TestItemRunner.jl")