From bf2999e284c02e0626965e2d1938788fa9bb88aa Mon Sep 17 00:00:00 2001 From: Wen Wei Tseng Date: Thu, 25 Jan 2024 19:58:42 +0800 Subject: [PATCH] CI (#299) * CI * workaround for steady state * fix --- .github/read_toml.py | 3 + .github/workflows/ci.yml | 193 ++++++++++++-------------- .github/workflows/linkcheck.yml | 112 ++++++++------- .github/workflows/update-manifest.yml | 107 +++++++------- Manifest.toml | 14 +- Project.toml | 2 - docs/figs/ch6-03.jl | 11 +- docs/figs/ch6-05.jl | 12 +- 8 files changed, 218 insertions(+), 236 deletions(-) create mode 100644 .github/read_toml.py diff --git a/.github/read_toml.py b/.github/read_toml.py new file mode 100644 index 00000000..0140ac06 --- /dev/null +++ b/.github/read_toml.py @@ -0,0 +1,3 @@ +import tomllib +with open("Manifest.toml", "rb") as f: + print(tomllib.load(f)["julia_version"]) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 78e832b2..a3cdbecf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,101 +1,92 @@ -name: Build notebooks and publish - -on: - workflow_dispatch: - push: - branches: [main] - pull_request: - branches: [main] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -env: - NPROC: '2' # Number of Julia processes to run the notebooks - CACHE_NUM: '1' - PY_VER: '3.12' - JULIA_CONDAPKG_BACKEND: 'Null' - JULIA_CI: 'true' - JULIA_NUM_THREADS: '2' - -jobs: - CI: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v5 - id: cp - with: - python-version: ${{ env.PY_VER }} - - name: Cache pip - uses: actions/cache@v4 - id: cache-pip - with: - path: ${{ env.pythonLocation }} - key: ${{ runner.os }}-pip-${{ steps.cp.outputs.python-version }}-${{ hashFiles('requirements.txt') }} - - name: Install python packages - if: ${{ steps.cache-pip.outputs.cache-hit != 'true' }} - run: pip install -r requirements.txt - - name: Read Julia version - uses: SebRollen/toml-action@v1.0.2 - id: read_toml - with: - file: 'Manifest.toml' - field: 'julia_version' - - name: Setup Julia - uses: julia-actions/setup-julia@v1 - with: - version: ${{ steps.read_toml.outputs.value }} - show-versioninfo: 'true' - - name: Cache Julia packages - uses: actions/cache/restore@v4 - id: cache-julia - with: - path: | - ~/.julia - !~/.julia/registries - key: ${{ runner.os }}-julia-${{ steps.read_toml.outputs.value }}-${{ env.CACHE_NUM }}-${{ hashFiles('src/**','Project.toml', 'Manifest.toml')}} - restore-keys: | - ${{ runner.os }}-julia-${{ steps.read_toml.outputs.value }}-${{ env.CACHE_NUM }}- - - name: Install Julia packages - if: ${{ steps.cache-julia.outputs.cache-hit != 'true' }} - run: | - julia --project=@. --color=yes -e 'using Pkg, Dates; Pkg.instantiate(); Pkg.precompile(); Pkg.gc(collect_delay=Day(0))' - - name: Save Julia packages - uses: actions/cache/save@v4 - if: ${{ steps.cache-julia.outputs.cache-hit != 'true' }} - with: - path: | - ~/.julia - !~/.julia/registries - key: ${{ steps.cache-julia.outputs.cache-primary-key }} - - name: Run program - run: julia --project=@. --color=yes -p ${{ env.NPROC }} literate.jl - - name: Build website - run: jupyter-book build docs/ - - name: Upload page artifact - if: ${{ github.ref == 'refs/heads/main' }} - uses: actions/upload-pages-artifact@v3 - with: - path: docs/_build/html - - # Deploy pages - deploy: - needs: CI - if: ${{ github.ref == 'refs/heads/main' }} - # Grant GITHUB_TOKEN the permissions required to make a Pages deployment - permissions: - pages: write # to deploy to Pages - id-token: write # to verify the deployment originates from an appropriate source - actions: read # to download an artifact uploaded by `actions/upload-pages-artifact@v3` - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 +name: Build notebooks and publish + +on: + workflow_dispatch: + push: + branches: [main] + pull_request: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + NPROC: '2' # Number of Julia processes to run the notebooks + CACHE_NUM: '1' + PY_VER: '3.12' + JULIA_CONDAPKG_BACKEND: 'Null' + JULIA_CI: 'true' + JULIA_NUM_THREADS: '2' + +jobs: + CI: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v5 + id: cp + with: + python-version: ${{ env.PY_VER }} + cache: 'pip' + - name: Install python packages + run: pip install -r requirements.txt + - name: Read Julia version + id: read_toml + run: echo "value=$(python .github/read_toml.py)" >> "$GITHUB_OUTPUT" + - name: Setup Julia + uses: julia-actions/setup-julia@v1 + with: + version: ${{ steps.read_toml.outputs.value }} + - name: Cache Julia packages + uses: actions/cache@v4 + id: cache-julia + with: + save-always: 'true' + path: | + ~/.julia + !~/.julia/registries + key: ${{ runner.os }}-julia-${{ env.CACHE_NUM }}-${{ hashFiles('src/**','Project.toml', 'Manifest.toml')}} + restore-keys: | + ${{ runner.os }}-julia-${{ env.CACHE_NUM }}- + - name: Install Julia packages + if: ${{ steps.cache-julia.outputs.cache-hit != 'true' }} + env: + PYTHON: ${{ env.pythonLocation }}/python + shell: julia --color=yes {0} + run: | + using Pkg, Dates + Pkg.add(["PrettyTables", "Literate"]) + Pkg.activate(".") + Pkg.instantiate() + Pkg.precompile() + Pkg.gc(collect_delay=Day(0)) + - name: Run program + run: julia --color=yes -p ${{ env.NPROC }} literate.jl + - name: Build website + run: jupyter-book build docs/ + - name: Upload page artifact + if: ${{ github.ref == 'refs/heads/main' }} + uses: actions/upload-pages-artifact@v3 + with: + path: docs/_build/html + + # Deploy pages + deploy: + needs: CI + if: ${{ github.ref == 'refs/heads/main' }} + # Grant GITHUB_TOKEN the permissions required to make a Pages deployment + permissions: + pages: write # to deploy to Pages + id-token: write # to verify the deployment originates from an appropriate source + actions: read # to download an artifact uploaded by `actions/upload-pages-artifact@v3` + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/linkcheck.yml b/.github/workflows/linkcheck.yml index 2b9048a4..8173a2e7 100644 --- a/.github/workflows/linkcheck.yml +++ b/.github/workflows/linkcheck.yml @@ -1,57 +1,55 @@ -name: Check markdown links - -on: - workflow_dispatch: - schedule: - - cron: '0 0 1 * *' # Every month - push: - branches: - - main - paths: - - 'docs/**' - - '.lycheeignore' - - '.github/workflows/linkcheck.yml' - -env: - DIR: 'docs' - PY_VER: '3.12' - -jobs: - linkcheck: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Setup Python - uses: actions/setup-python@v5 - id: cp - with: - python-version: ${{ env.PY_VER }} - - name: Cache pip - uses: actions/cache@v4 - id: cache-pip - with: - path: ${{ env.pythonLocation }} - key: ${{ runner.os }}-pip-${{ steps.cp.outputs.python-version }}-${{ hashFiles('requirements.txt') }} - - name: Install python packages - if: ${{ steps.cache-pip.outputs.cache-hit != 'true' }} - run: pip install -r requirements.txt - - name: Setup Julia - uses: julia-actions/setup-julia@v1 - - name: Convert literate notebooks to markdown files - shell: julia --color=yes {0} - working-directory: ${{ env.DIR }} - run: | - import Pkg - Pkg.add("Literate") - using Literate - for (root, dirs, files) in walkdir(pwd()) - for file in files - if endswith(file, ".jl") - nb = joinpath(root, file) - Literate.notebook(nb, dirname(nb); mdstrings=true, execute=false) - end - end - end - - name: Check links - run: jupyter-book build ${DIR} --builder linkcheck +name: Check markdown links + +on: + workflow_dispatch: + schedule: + - cron: '0 0 1 * *' # Every month + push: + branches: + - main + paths: + - 'docs/**' + - '.lycheeignore' + - '.github/workflows/linkcheck.yml' + +env: + DIR: 'docs' + +jobs: + linkcheck: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Julia + uses: julia-actions/setup-julia@v1 + - name: Convert literate notebooks to markdown files + shell: julia --color=yes {0} + working-directory: ${{ env.DIR }} + run: | + import Pkg + Pkg.add("Literate") + using Literate + for (root, dirs, files) in walkdir(pwd()) + for file in files + if endswith(file, ".jl") + Literate.markdown(joinpath(root, file); mdstrings=true, flavor = Literate.CommonMarkFlavor()) + end + end + end + - name: Restore lychee cache + id: restore-cache + uses: actions/cache@v4 + with: + save-always: 'true' + path: .lycheecache + key: cache-lychee-${{ github.sha }} + restore-keys: cache-lychee- + - name: Lychee Checker + uses: lycheeverse/lychee-action@v1.9.1 + id: lychee + with: + fail: true + args: '--accept 200,204,429 --verbose --no-progress --cache --max-cache-age 1d ${{ env.DIR }}' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/update-manifest.yml b/.github/workflows/update-manifest.yml index 53429363..c381ed31 100644 --- a/.github/workflows/update-manifest.yml +++ b/.github/workflows/update-manifest.yml @@ -1,54 +1,53 @@ -name: Auto update Julia dependencies - -on: - workflow_dispatch: - schedule: - - cron: '0 0 * * 1' # Every week - push: - branches: - - main - paths: - - .github/workflows/update-manifest.yml - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -env: - APP_ID: '189113' # https://github.com/apps/wen-wei-s-pr-bot - JL_VER: '1' - -jobs: - update-manifest: - permissions: - contents: write - pull-requests: write - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Setup Julia - uses: julia-actions/setup-julia@v1 - with: - version: ${{ env.JL_VER }} - - name: Update Julia dependencies - env: - JULIA_PKG_PRECOMPILE_AUTO: '0' - JULIA_PROJECT: '@.' - run: julia --color=yes -e 'import Pkg; Pkg.update()' - # Authenticate with a custom GitHub APP - # https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#authenticating-with-github-app-generated-tokens - - name: Generate token for PR - uses: tibdex/github-app-token@v2 - id: generate-token - with: - app_id: ${{ env.APP_ID }} - private_key: ${{ secrets.APP_PRIVATE_KEY }} - - name: Create Pull Request - id: cpr - uses: peter-evans/create-pull-request@v5 - with: - title: Julia Dependency Update - token: ${{ steps.generate-token.outputs.token }} - labels: | - automerge +name: Auto update Julia dependencies + +on: + workflow_dispatch: + schedule: + - cron: '0 0 * * 1' # Every week + push: + branches: + - main + paths: + - .github/workflows/update-manifest.yml + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + APP_ID: '189113' # https://github.com/apps/wen-wei-s-pr-bot + JL_VER: '1' + +jobs: + update-manifest: + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Julia + uses: julia-actions/setup-julia@v1 + with: + version: ${{ env.JL_VER }} + - name: Update Julia dependencies + env: + JULIA_PKG_PRECOMPILE_AUTO: '0' + run: julia --project=@. --color=yes -e 'import Pkg; Pkg.update()' + # Authenticate with a custom GitHub APP + # https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#authenticating-with-github-app-generated-tokens + - name: Generate token for PR + uses: tibdex/github-app-token@v2 + id: generate-token + with: + app_id: ${{ env.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + - name: Create Pull Request + id: cpr + uses: peter-evans/create-pull-request@v5 + with: + title: Julia Dependency Update + token: ${{ steps.generate-token.outputs.token }} + labels: | + automerge diff --git a/Manifest.toml b/Manifest.toml index 89b721c9..10baee80 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.0" manifest_format = "2.0" -project_hash = "e8b21c1e5d769fc083d79201240ba21b18bf6a7e" +project_hash = "7e5807e059f83e7dc9033cceb2df5b3a68479e06" [[deps.ADTypes]] git-tree-sha1 = "41c37aa88889c171f1300ceac1313c06e891d245" @@ -730,12 +730,6 @@ git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" version = "0.3.23" -[[deps.IOCapture]] -deps = ["Logging", "Random"] -git-tree-sha1 = "8b72179abc660bfab5e28472e019392b97d0985c" -uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" -version = "0.2.4" - [[deps.IfElse]] git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" @@ -1055,12 +1049,6 @@ version = "2.22.1" Pardiso = "46dd5b70-b6fb-5a00-ae2d-e8fea33afaf2" RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" -[[deps.Literate]] -deps = ["Base64", "IOCapture", "JSON", "REPL"] -git-tree-sha1 = "bad26f1ccd99c553886ec0725e99a509589dcd11" -uuid = "98b081ad-f1c9-55d3-8b20-4c87d4299306" -version = "2.16.1" - [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] git-tree-sha1 = "7d6dd4e9212aebaeed356de34ccf262a3cd415aa" diff --git a/Project.toml b/Project.toml index ee8c000f..f4bd63c0 100644 --- a/Project.toml +++ b/Project.toml @@ -6,10 +6,8 @@ DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa" Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" -Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SimpleUnPack = "ce78b400-467f-4804-87d8-8f486da07d0a" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" diff --git a/docs/figs/ch6-03.jl b/docs/figs/ch6-03.jl index 271e70c0..71fd2a93 100644 --- a/docs/figs/ch6-03.jl +++ b/docs/figs/ch6-03.jl @@ -66,12 +66,15 @@ prob_func = function(prob, i, repeat) remake(prob, p=p) end -prob = SteadyStateProblem(osys, [], []) +prob = ODEProblem(osys, [], Inf, []) +callback = TerminateSteadyState() +trajectories = length(lrange) +alg = Rodas5() eprob = EnsembleProblem(prob; prob_func) -sim = solve(eprob, DynamicSS(Rodas5()); trajectories=length(lrange)) +sim = solve(eprob, alg; save_everystep=false, trajectories, callback) -pstar = map(s->s[Ps], sim) -rl = map(s->s[RL], sim) +pstar = map(s->s[Ps][end], sim) +rl = map(s->s[RL][end], sim) fig = plot(lrange, [pstar rl], label=["P*" "RL"], title="Fig. 6.3 (B)", xlabel="Ligand", ylabel="Steady-state concentration", xlims=(0, 1), ylims=(0, 8)) diff --git a/docs/figs/ch6-05.jl b/docs/figs/ch6-05.jl index ef3a1599..ab4af082 100644 --- a/docs/figs/ch6-05.jl +++ b/docs/figs/ch6-05.jl @@ -61,7 +61,6 @@ fig = plot(sol, idxs=[RL, Ga], title="Fig 6.05 (A)", xlabel="Time", ylabel="Abun fig |> PNG # ## Fig 6.5 B - lrange = range(0, 20 * 1e-9, 101) prob_func = function(prob, i, repeat) @@ -70,12 +69,15 @@ prob_func = function(prob, i, repeat) remake(prob, p=p) end -prob = SteadyStateProblem(osys, []) +prob = ODEProblem(osys, [], Inf, []) +callback = TerminateSteadyState() +trajectories = length(lrange) +alg = Rodas5() eprob = EnsembleProblem(prob; prob_func) -sim = solve(eprob, DynamicSS(Rodas5()); trajectories=length(lrange)) +sim = solve(eprob, alg; save_everystep=false, trajectories, callback) -ga = map(s->s[Ga], sim) -rl = map(s->s[RL], sim) +ga = map(s->s[Ga][end], sim) +rl = map(s->s[RL][end], sim) fig = plot(lrange .* 1e9, [ga rl], label=["Ga" "RL"], title="Fig. 6.5 (B)", xlabel="Ligand (nM)", ylabel="Steady-state abundance", xlims=(0, 20), ylims=(0, 3500))