diff --git a/.buildkite/jobscript.sh b/.buildkite/jobscript.sh new file mode 100755 index 0000000..c889859 --- /dev/null +++ b/.buildkite/jobscript.sh @@ -0,0 +1,9 @@ +pwd; hostname; date + +module load julia + +echo "Running Tests..." +julia --project -t 32 -e 'using Pkg; Pkg.status(); Pkg.test()' + +echo "Building Documentation..." +julia --project=docs -t 32 -e'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.status(); Pkg.instantiate(); include("docs/make.jl")' diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml new file mode 100644 index 0000000..63e3ca3 --- /dev/null +++ b/.buildkite/pipeline.yml @@ -0,0 +1,20 @@ +env: + JULIA_VERSION: "1.9.3" + +steps: + + - label: ":hammer: Build Project" + command: + - "module load julia" + - "julia --project=docs --color=yes -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate(); Pkg.precompile()'" + + - wait + + - label: ":scroll: Build docs and run tests" + command: + - "srun --cpus-per-task=32 --mem=8G --time=1:00:00 --output=.buildkite/log_%j.log --unbuffered .buildkite/jobscript.sh" + env: + JULIA_PROJECT: "docs/" + + - wait + diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml new file mode 100644 index 0000000..b2e776d --- /dev/null +++ b/.github/workflows/TagBot.yml @@ -0,0 +1,30 @@ +name: TagBot +on: + issue_comment: + 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' + runs-on: ubuntu-latest + steps: + - uses: JuliaRegistries/TagBot@v1 + with: + token: ${{ secrets.SERVICE_TOKEN }} diff --git a/.github/workflows/julia_ci.yml b/.github/workflows/julia_ci.yml new file mode 100644 index 0000000..9dabe35 --- /dev/null +++ b/.github/workflows/julia_ci.yml @@ -0,0 +1,50 @@ +name: Julia CI/CD + +on: + schedule: + - cron: 0 0 * * * + push: + branches: ["main"] + tags: ["*"] + pull_request: + workflow_dispatch: + inputs: + action: + description: "Action" + required: true + default: "test" + type: choice + options: + - test + - release + version: + description: "Tag and release version:" + required: false + +permissions: + actions: read + checks: read + contents: write + deployments: read + discussions: read + issues: read + packages: read + pages: read + pull-requests: write + repository-projects: read + security-events: read + statuses: read + +jobs: + CI: + if: github.event_name == 'pull_request' || github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.action == 'test') + uses: AlgebraicJulia/.github/.github/workflows/julia_ci.yml@main + secrets: inherit + CompatHelper: + if: github.event_name == 'schedule' + uses: AlgebraicJulia/.github/.github/workflows/julia_compat.yml@main + secrets: inherit + Release: + if: github.event_name == 'workflow_dispatch' && inputs.action == 'release' && inputs.version != '' + uses: AlgebraicJulia/.github/.github/workflows/julia_release.yml@main + secrets: inherit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3be7528 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Files generated by invoking Julia with --code-coverage +*.jl.cov +*.jl.*.cov + +# Files generated by invoking Julia with --track-allocation +*.jl.mem + +# Files generated by benchmarktools +.benchmarkci +benchmark/*.json + +# System-specific files and directories generated by the BinaryProvider and BinDeps packages +# They contain absolute paths specific to the host computer, and so should not be committed +deps/deps.jl +deps/build.log +deps/downloads/ +deps/usr/ +deps/src/ + +# File generated by Pkg, the package manager, based on a corresponding Project.toml +# It records a fixed state of all packages used by the project. As such, it should not be +# committed for packages, but should be committed for applications that require a static +# environment. +Manifest.toml + +# Misc. System Files +.DS_Store +.vscode +.ipynb_checkpoints diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ccd1787 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 AlgebraicJulia + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Project.toml b/Project.toml new file mode 100644 index 0000000..639d35b --- /dev/null +++ b/Project.toml @@ -0,0 +1,12 @@ +name = "AlgebraicTemplate" +uuid = "b66562e1-fa90-4e8b-9505-c909188fab76" +license = "MIT" +authors = ["AlgebraicJulia Developer "] +version = "0.0.1" + +[deps] +Catlab = "134e5e36-593f-5add-ad60-77f754baafbe" + +[compat] +Catlab = "^0.16" +julia = "1.6" diff --git a/README.md b/README.md new file mode 100644 index 0000000..2f0df12 --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +# AlgebraicTemplate.jl + +[![Stable Documentation](https://img.shields.io/badge/docs-stable-blue.svg)](https://AlgebraicJulia.github.io/AlgebraicTemplate.jl/stable) +[![Development Documentation](https://img.shields.io/badge/docs-dev-blue.svg)](https://AlgebraicJulia.github.io/AlgebraicTemplate.jl/dev) +[![Code Coverage](https://codecov.io/gh/AlgebraicJulia/AlgebraicTemplate.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/AlgebraicJulia/AlgebraicTemplate.jl) +[![CI/CD](https://github.com/AlgebraicJulia/AlgebraicTemplate.jl/actions/workflows/julia_ci.yml/badge.svg)](https://github.com/AlgebraicJulia/AlgebraicTemplate.jl/actions/workflows/julia_ci.yml) + +A template repository for making a new AlgebraicJulia package. + +## 🛠️ Usage + +1. Use the "Use this template" dropdown to select "Create a new repository" +2. In the new page select "AlgebraicJulia" as the owner, give the repository a name, and create a new repository from the template +3. Set up Codecov credentials for code coverage (If you have trouble, reach out to an AlgebraicJulia organization owner to help with this) + + 1. Log into [Codecov](https://codecov.io) with your GitHub account (this requires that you are a member of the AlgebraicJulia organization) + 2. Navigate to the [AlgebraicJulia organization](https://app.codecov.io/gh/AlgebraicJulia) + 3. Select your new repository from the list (e.x. "AlgebraicX") + 4. Note down the `CODECOV_TOKEN` value (It may be in the "Settings" tab if it doesn't show up immediately) + 5. Navigate back to your new GitHub repository and go to the Settings tab + 6. Go to "Security", "Secrets and variables", and "Actions" and click the "New repository secret" button + 7. Give the secret name `CODECOV_TOKEN` and the Secret value is the value you noted from the Codecov settings + 8. Click "Add secret" + +4. Clone the new repository, for example in the terminal: + ```sh + git clone https://github.com/AlgebraicJulia/AlgebraicX.jl.git + cd AlgebraicX.jl + ``` +5. Inspect for yourself and run `init.sh` with the new repository name and (optional) UUID are parameters. This script will substitute all instances of `AlgebraicX` with your new repository name and the default UUID with a new one or, if available, the UUID provided. +6. Go back to your repository and wait until the tests have passed, you can check the status by going to the "Actions" tab in the repository + +### Buildkite + +AlgebraicJulia uses [Buildkite](https://buildkite.com/) to submit resource-intensive processes such as building documentation and executing tests to the [HiPerGator](https://www.rc.ufl.edu/about/hipergator/) computing cluster. + +While this template comes with a preconfigured `.buildkite/pipeline.yml` file, this repository is not integrated with Buildkite by default. If you would like your repository to use Buildkite to run processes on HiPerGator, tag an issue with @AlgebraicJulia/SysAdmins. + +### 📔 Set Up GitHub Pages (Public Repos Only) + +1. Follow the Usage steps above to set up a new template, make sure all initial GitHub Actions have passed +2. Navigate to the repository settings and go to "Code and automation", "Pages" +3. Make sure the "Source" dropdown is set to "Deploy from a branch" +4. Set the "Branch" dropdown to "gh-pages", make sure the folder is set to "/ (root)", and click "Save" +5. Go back to the main page of your repository and click the gear to the right of the "About" section in the right side column +6. Under "Website" check the checkbox that says "Use your GitHub Pages website" and click "Save changes" +7. You will now see a URL in the "About" section that will link to your package's documentation + +### 🛡️ Set Up Branch Protection (Public Repos Only) + +1. Follow the Usage steps above to set up a new template, make sure all initial GitHub Actions have passed +2. Navigate to the repository settings and go to "Code and automation", "Branches" +3. Click "Add branch protection rule" to start adding branch protection +4. Under "Branch name pattern" put `main`, this will add protection to the main branch +5. Make sure to set the following options: + - Check the "Require a pull request before merging" + - Check the "Request status checks to pass before merging" and make sure the following status checks are added to the required list: + - CI / Documentation + - CI / Julia 1 - ubuntu-latest - x64 - push + - CI / Julia 1 - ubuntu-latest - x86 - push + - CI / Julia 1 - windows-latest - x64 - push + - CI / Julia 1 - windows-latest - x86 - push + - CI / Julia 1 - macOS-latest - x64 - push + - Check the "Restrict who can push to matching branches" and add `algebraicjuliabot` to the list of people with push access +6. Click "Save changes" to enable the branch protection diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..ce86316 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,11 @@ +coverage: + precision: 2 + status: + patch: + default: + target: 0% + threshold: 100% + project: + default: + target: 0% + threshold: 100% diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..cff0b76 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,2 @@ +build/ +src/generated/ diff --git a/docs/Project.toml b/docs/Project.toml new file mode 100644 index 0000000..f26c9b1 --- /dev/null +++ b/docs/Project.toml @@ -0,0 +1,4 @@ +[deps] +AlgebraicTemplate = "b66562e1-fa90-4e8b-9505-c909188fab76" +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" diff --git a/docs/literate/literate_example.jl b/docs/literate/literate_example.jl new file mode 100644 index 0000000..bd5f878 --- /dev/null +++ b/docs/literate/literate_example.jl @@ -0,0 +1,13 @@ +# # Code Example +# +# This is an example of adding a code example compiled with Literate.jl in the docs. +# +# First we want to load our package with `using` + +using AlgebraicTemplate + +# ## Using `hello()` +# +# We provide the `hello(string)` method which prints "Hello, `string`!" + +hello("World") diff --git a/docs/make.jl b/docs/make.jl new file mode 100644 index 0000000..862f5f7 --- /dev/null +++ b/docs/make.jl @@ -0,0 +1,56 @@ +using Documenter +using Literate + +const literate_dir = joinpath(@__DIR__, "literate") +const generated_dir = joinpath(@__DIR__, "src", "generated") + +@info "Loading AlgebraicTemplate" +using AlgebraicTemplate + +const no_literate = "--no-literate" in ARGS +if !no_literate + @info "Building Literate.jl docs" + + # Set Literate.jl config if not being compiled on recognized service. + config = Dict{String,String}() + if !(haskey(ENV, "GITHUB_ACTIONS") || haskey(ENV, "GITLAB_CI")) + config["nbviewer_root_url"] = "https://nbviewer.jupyter.org/github/AlgebraicJulia/AlgebraicTemplate.jl/blob/gh-pages/dev" + config["repo_root_url"] = "https://github.com/AlgebraicJulia/AlgebraicTemplate.jl/blob/main/docs" + end + + for (root, dirs, files) in walkdir(literate_dir) + out_dir = joinpath(generated_dir, relpath(root, literate_dir)) + for file in files + f, l = splitext(file) + if l == ".jl" && !startswith(f, "_") + Literate.markdown(joinpath(root, file), out_dir; + config=config, documenter=true, credit=false) + Literate.notebook(joinpath(root, file), out_dir; + execute=true, documenter=true, credit=false) + end + end + end +end + +@info "Building Documenter.jl docs" +makedocs( + modules=[AlgebraicTemplate], + format=Documenter.HTML(), + sitename="AlgebraicTemplate.jl", + doctest=false, + checkdocs=:none, + pages=Any[ + "AlgebraicTemplate.jl"=>"index.md", + "Examples"=>Any[ + "generated/literate_example.md", + ], + "Library Reference"=>"api.md", + ] +) + +@info "Deploying docs" +deploydocs( + target="build", + repo="github.com/AlgebraicJulia/AlgebraicTemplate.jl.git", + branch="gh-pages" +) diff --git a/docs/src/api.md b/docs/src/api.md new file mode 100644 index 0000000..38b269d --- /dev/null +++ b/docs/src/api.md @@ -0,0 +1,5 @@ +# Library Reference + +```@autodocs +Modules = [AlgebraicTemplate] +``` diff --git a/docs/src/index.md b/docs/src/index.md new file mode 100644 index 0000000..d3f8de2 --- /dev/null +++ b/docs/src/index.md @@ -0,0 +1,7 @@ +# AlgebraicTemplate.jl + +```@meta +CurrentModule = AlgebraicTemplate +``` + +`AlgebraicTemplate.jl` is a Julia library for... diff --git a/init.sh b/init.sh new file mode 100755 index 0000000..ff4813a --- /dev/null +++ b/init.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +DEFAULT_REPO='AlgebraicTemplate' +DEFAULT_UUID='b66562e1-fa90-4e8b-9505-c909188fab76' + +usage="This script is for initializing the template with the new repository name and UUID. Please provide the new repository name and UUID in that order. The repository name cannot be 'Test.'\n +Example:\n +./init.sh ${DEFAULT_REPO} ${DEFAULT_UUID}" + +REPO=${1:-"${PWD##*/}"} +UUID=${2:-$(uuidgen)} + +# set to lowercase +UUID=${UUID,,} + +if [ ! $REPO ] || [ "$REPO" = 'Test' ] || [ ! $UUID ]; then + echo "" + printf "$usage" + exit 1 +fi + +read -p "By continuing, the following substitutions will be made: + +REPO: $DEFAULT_REPO => $REPO +UUID: $DEFAULT_UUID => $UUID + +Are you sure? [y/N]" -n 1 -r -s +echo + +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + exit 1 +fi + +echo "Doing the thing..." + +# get version +unameOut="$(uname -s)" + +case "${unameOut}" in + Linux*) + git grep -l $DEFAULT_REPO | xargs sed -i "s/${DEFAULT_REPO}/${REPO}/g"; + git grep -l $DEFAULT_UUID | xargs sed -i "s/${DEFAULT_UUID}/${UUID}/g";; + Darwin*) + git grep -l $DEFAULT_REPO | xargs sed -i '' -e "s/${DEFAULT_REPO}/${REPO}/g"; + git grep -l $DEFAULT_UUID | xargs sed -i '' -e "s/${DEFAULT_UUID}/${UUID}/g";; + *) + echo UNKNOWN:${unameOut};; +esac + +# rename +if [[ $REPO == *.jl ]] +then + mv src/$DEFAULT_REPO.jl src/$REPO +else + mv src/$DEFAULT_REPO.jl src/$REPO.jl +fi + +read -p "Would you like this script to add, commit, and push the new changes? [y/N]" -n 1 -r -s +echo + +if [[ ! $REPLY =~ ^[Yy]$ ]] +then + exit 1 +fi + +git commit -am "Initialized $REPO" +git push diff --git a/src/AlgebraicTemplate.jl b/src/AlgebraicTemplate.jl new file mode 100644 index 0000000..e86b143 --- /dev/null +++ b/src/AlgebraicTemplate.jl @@ -0,0 +1,15 @@ +""" Some description of ths package +""" +module AlgebraicTemplate + +export hello + +using Catlab + +""" hello(name::String) + +Returns the string "Hello, !" where `` is replaced with the provided parameter +""" +hello(name::String) = string("Hello, ", name, "!") + +end diff --git a/test/Project.toml b/test/Project.toml new file mode 100644 index 0000000..3f84432 --- /dev/null +++ b/test/Project.toml @@ -0,0 +1,4 @@ +[deps] +AlgebraicTemplate = "b66562e1-fa90-4e8b-9505-c909188fab76" +Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/test/aqua.jl b/test/aqua.jl new file mode 100644 index 0000000..655c40f --- /dev/null +++ b/test/aqua.jl @@ -0,0 +1,3 @@ +using Aqua, AlgebraicTemplate + +Aqua.test_all(AlgebraicTemplate, ambiguities=false,) diff --git a/test/core.jl b/test/core.jl new file mode 100644 index 0000000..d9bf789 --- /dev/null +++ b/test/core.jl @@ -0,0 +1 @@ +@test hello("World") == "Hello, World!" diff --git a/test/runtests.jl b/test/runtests.jl new file mode 100644 index 0000000..16e23d8 --- /dev/null +++ b/test/runtests.jl @@ -0,0 +1,9 @@ +using Test + +@testset "Code Quality (Aqua.jl)" begin + include("aqua.jl") +end + +@testset "Core" begin + include("core.jl") +end