diff --git a/.github/workflows/commit.yml b/.github/workflows/commit.yml index 528f5c36..8bd8afbd 100644 --- a/.github/workflows/commit.yml +++ b/.github/workflows/commit.yml @@ -1,3 +1,4 @@ +# Updates the dev docs every time a new commit is pushed to main. name: Commit Pipeline concurrency: docs-push diff --git a/.github/workflows/dummy_pr.yml b/.github/workflows/dummy_pr.yml index 9d87ef62..89c216a7 100644 --- a/.github/workflows/dummy_pr.yml +++ b/.github/workflows/dummy_pr.yml @@ -1,3 +1,10 @@ +# We want to limit the cost of our CI to the OpenDP organization, so we only +# want to run linters/tests/docs when a PR is about to be merged, not every time +# we push. However, due to limitations of how the GitHub Merge Queue works, we +# have to create a workflow that triggers on each PR, with the same job names as the +# ones we want to run at merge time. See +# https://github.com/opendp/tumult-analytics/issues/1#issuecomment-2936533302 +# for more details. name: PR Dummy Pipeline on: diff --git a/.github/workflows/merge_queue.yml b/.github/workflows/merge_queue.yml index 871cd0c5..25eb3fdf 100644 --- a/.github/workflows/merge_queue.yml +++ b/.github/workflows/merge_queue.yml @@ -1,3 +1,4 @@ +# Runs linters, run tests, and checks that the docs build when a PR is about to be merged. name: Merge Queue Pipeline on: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index eb8fda3b..0759991b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,3 +1,7 @@ +# This pipeline is executed every time someone pushes a tag to GitHub. If the +# tag is a valid version number, it builds the library, runs the slow tests and +# the benchmarks, pushes the package distribution to PyPI, and if this is a +# production release, also publishes the docs. name: Release Pipeline on: @@ -16,7 +20,8 @@ jobs: runs-on: ubuntu-latest steps: - run: | - if [[ ! "$GITHUB_REF_NAME" =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-(dev|alpha|beta|rc)\.(0|[1-9][0-9]*))?$ ]]; then + re="^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-(alpha|beta|rc)\.(0|[1-9][0-9]*))?$" + if [[ ! "$GITHUB_REF_NAME" =~ $re ]]; then echo "Tag $GITHUB_REF_NAME is not a valid version number. Aborting release pipeline." exit 1 fi @@ -69,3 +74,53 @@ jobs: path: dist - run: uv run nox -t benchmark + Publish-To-PyPI: + if: github.repository == 'opendp/tumult-analytics' + runs-on: ubuntu-latest + needs: + - Test-Slow + - Benchmark + environment: + name: pypi + url: https://pypi.org/p/tmlt-analytics + permissions: + id-token: write + steps: + - name: Download package distributions + uses: actions/download-artifact@v4 + with: + name: dist + path: dist + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + + Push-Docs: + if: ${{ github.repository == 'opendp/tumult-analytics' + && ! contains(github.ref_name, 'alpha') + && ! contains(github.ref_name, 'beta') + && ! contains(github.ref_name, 'rc') }} + runs-on: ubuntu-latest + environment: docs-push + needs: Publish-To-PyPI + steps: + - name: Checkout code repository + uses: actions/checkout@v4 + - name: Set up runner + uses: opendp/tumult-tools/actions/setup@0f3d49599e5824a9f407a6e2063990c1e0d4c2e8 + - name: Download dist + uses: actions/download-artifact@v4 + with: + name: dist + path: dist + - run: | + re="^([0-9]+)\.([0-9]+).*$" + [[ $GITHUB_REF_NAME =~ $re ]] + echo "MAJOR_VERSION=${BASH_REMATCH[1]}" >> $GITHUB_ENV + echo "MINOR_VERSION=${BASH_REMATCH[2]}" >> $GITHUB_ENV + - name: Push docs + uses: opendp/tumult-tools/actions/push_docs@1c7b4b3cfa98ab75f3c5b0b91858c897a81629ad + with: + docs-repository: opendp/tumult-docs + docs-repository-token: ${{ secrets.DOCS_REPO_PAT }} + docs-path: docs/analytics + version: ${{ format('v{0}.{1}', env.MAJOR_VERSION, env.MINOR_VERSION) }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 59d64e76..a6d2b909 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -61,6 +61,18 @@ the generated HTML pages are available in the `public` directory. Note that our API reference is manually organized, and does not follow the internal package structure. If you add a new public class or method to Tumult Analytics, add it to an `autosummary` directive in the relevant `.rst` file under `doc/reference`. +### Continuous integration + +We use GitHub Actions to automatically run some jobs under specific conditions. +The definition of these jobs can be found in [`.github/workflows`](./.github/workflows). + +To try it out a newly modified action before merging the PR, you can change the trigger to the definition file to execute whenever you push on your branch: +```yaml +on: + push: + branch: your_username/your_branch +``` + ### Cleanup Running linters, tests, or building docs tends to generate a lot of files in the repository that you generally don't want to keep around. Simply run `make clean` to get rid of all those. This is particularly useful when working on the documentation; Sphinx tends to get confused by files generated in previous documentation builds.