Skip to content

Commit

Permalink
updated notes from 524
Browse files Browse the repository at this point in the history
  • Loading branch information
ttimbers committed Apr 10, 2024
1 parent bd73748 commit 5603ca8
Show file tree
Hide file tree
Showing 18 changed files with 3,719 additions and 1,029 deletions.
267 changes: 267 additions & 0 deletions docs/_sources/materials/lectures/12-deploy-and-publish.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,86 @@
"- Books and websites (e.g., [`jupyter-book`](https://jupyterbook.org/intro.html), [`bookdown`](https://bookdown.org/), [`distill` websites](https://pkgs.rstudio.com/distill/index.html), etc)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Conditionals for when to run the job\n",
"\n",
"We only want our `cd` job to run if certain conditions are true, these are:\n",
"\n",
"1. if the `ci` job passes\n",
"\n",
"2. if this is a commit to the `main` branch\n",
"\n",
"We can accomplish this in our `cd` job be writing a conditional using the `needs` and `if` keywords at the top of the job, right after we set the permissions:\n",
"\n",
"```\n",
"cd:\n",
" permissions:\n",
" id-token: write\n",
" contents: write\n",
"\n",
" # Only run this job if the \"ci\" job passes\n",
" needs: ci\n",
"\n",
" # Only run this job if new work is pushed to \"main\"\n",
" if: github.event_name == 'push' && github.ref == 'refs/heads/main'\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Exercise: read the `cd` job of [`ci-cd.yml`](https://github.com/py-pkgs/py-pkgs-cookiecutter/blob/main/%7B%7B%20cookiecutter.__package_slug%20%7D%7D/.github/workflows/ci-cd.yml)\n",
"\n",
"To make sure we understand what is happening in our workflow that performs CD, let's convert each **step** to a human-readable explanation:\n",
"\n",
"1. Sets up Python on the runner\n",
"\n",
"2. Checkout our repository files from GitHub and put them on the runner\n",
"\n",
"3. ...\n",
"\n",
"4. ...\n",
"\n",
"5. ...\n",
"\n",
"6. ...\n",
"\n",
"7. ...\n",
"\n",
"> Note: I filled in the steps we went over last class, so you can just fill in the new stuff"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### How can we automate version bumping?\n",
"\n",
"Let's look at the first step that works towards accomplishing this:\n",
"\n",
"```\n",
" - name: Use Python Semantic Release to prepare release\n",
" id: release\n",
" uses: python-semantic-release/python-semantic-release@v8.3.0\n",
" with:\n",
" github_token: ${{ secrets.GITHUB_TOKEN }}\n",
"```\n",
"\n",
"[Python semantic-release](https://python-semantic-release.readthedocs.io/en/latest/) is a Python tool which parses commit messages looking for keywords to indicate how to bump the version. It bumps the version in the `pyproject.toml` file.\n",
"\n",
"To understand how it works so that we can use it, we need to understand **semantic versioning** and how to write **conventional commit** messages.\n",
"\n",
"Let's unpack each of these on its own."
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down Expand Up @@ -135,6 +215,193 @@
"Reading the three cases posted above, think about whether each should be a major, minor or patch version bump. Answer the chat when prompted."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Conventional commit messages\n",
"\n",
"[Python Semantic Release](https://python-semantic-release.readthedocs.io/en/latest/) by default uses a parser that works on the conventional (or Angular) commit message style, which is:\n",
"\n",
"```\n",
"<type>(optional scope): succinct description of the change\n",
"\n",
"(optional body: the motivation for the change and contrast this with previous behavior)\n",
"\n",
"(optional footer: note BREAKING CHANGES here, as well as any issues to be closed)\n",
"```\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"How to affect semantic versioning with conventional commit messages:\n",
"- a commit with the type `fix` leads to a patch version bump\n",
"- a commit with the type `feat` leads to a minor version bump\n",
"- a commit with a body or footer that starts with `BREAKING CHANGE:` - these can be of any type (Note: currently Python Semantic release is broken for detecting these on commits with Windows line endings, wich the GitHub pen tool commits also use. The workaround fix is to use `!` after `feat`, for example: `feat!: This describes the new feature and breaking changes` in addition to `BREAKING CHANGES: ...` in the footer.)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"source": [
"> Note - commit types other than `fix` and `feat` are allowed. Recommeneded ones include `docs`, `style`, `refactor`, `test`, `ci` and [others](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#type). However, only `fix` and `feat` result in version bumps using Python Semantic Release."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### An example of a conventional commit message\n",
"\n",
"```\n",
"git commit -m \"feat(function_x): added the ability to initialize a project even if a pyproject.toml file exists\"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"What kind of version bump would this result in?"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Another example of a conventional commit message\n",
"\n",
"```\n",
"git commit -m \"feat!: change to use of `%>%` to add new layers to ggplot objects\n",
"\n",
"BREAKING CHANGE: `+` operator will no longer work for adding new layers to ggplot objects after this release\"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"What kind of version bump would this result in?"
]
},
{
"cell_type": "markdown",
"metadata": {
"jp-MarkdownHeadingCollapsed": true,
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Some practical notes for usage in your packages:\n",
"\n",
"1. You must add the following to the tool section of your `pyproject.toml` file for this to work (note: the `pypkgs-cookiecutter` adds this table if you choose to add `ci-cd` when you set it up):\n",
"\n",
" ```\n",
" [tool.semantic_release]\n",
" version_toml = [\n",
" \"pyproject.toml:tool.poetry.version\",\n",
" ] # version location\n",
" branch = \"main\" # branch to make releases of\n",
" changelog_file = \"CHANGELOG.md\" # changelog file\n",
" build_command = \"pip install poetry && poetry build\" # build dists\n",
" ```\n",
" \n",
"2. Versions will **not** be bumped if conventional commits are not used."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Some practical notes for usage in your packages:\n",
"\n",
"\n",
"1. Automated version bumping can only work (as currently implemented in our cookiecutter) with versions in the `pyproject.toml` metadata (line 3). If you add a version elsewhere, it will not get bumped unless you specify the location the the `[tool.semantic_release]` table in `pyproject.toml`.\n",
"\n",
"2. If you have been working with main branch protection, you will need to change something to use `ci.yml` work for continuous deployment. The reason for this, is that this workflow (which bumps versions and deploy the package) is triggered to run **after** the pull request is merged to main. Therefore, when we bump the versions in the `pyproject.toml` file we need to push these changes to the main branch - however this is problematic given that we have set-up main branch protection!\n",
"\n",
"What are we to do about #2?\n",
"\n",
"#### Solution 1: \n",
"\n",
"Remove main branch protection. This is not the most idealistic solution, however it is a simple and practical one.\n",
"\n",
"#### Possible solution 2: \n",
"\n",
"(I say possible because this has yet to be formally documented by PSR, and is still just reported in an issue: <https://github.com/python-semantic-release/python-semantic-release/issues/311>. I have tested it and it works for me, see example here: <https://github.com/ttimbers/pycounts_tt_2024/blob/main/.github/workflows/ci-cd.yml>)\n",
"\n",
"1. Create a new GitHub PAT (see [these docs](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)) with the [repo](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps#available-scopes) scope.\n",
"\n",
"2. Under **\"Secrets\"**, click on **\"Settings and variables\"** > **\"Actions\"**, and then under **\"Repository secrets\"** click **\"New repository secret\"** to create a new repository secret named `RELEASE_TOKEN` and the new GitHub PAT with repo scope as its value.\n",
"\n",
"3. Edit the to `cd` job steps shown below (from `ci-cd.yml`) use this token:\n",
"\n",
"```\n",
"...\n",
" - uses: actions/checkout@v3\n",
" with:\n",
" fetch-depth: 0\n",
" token: ${{ secrets.RELEASE_TOKEN }}\n",
"...\n",
"\n",
" - name: Use Python Semantic Release to prepare release\n",
" id: release\n",
" uses: python-semantic-release/python-semantic-release@v8.3.0\n",
" with:\n",
" github_token: ${{ secrets.RELEASE_TOKEN }}\n",
"...\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Demo of Continous Deployment!\n",
"\n",
"- <https://github.com/ttimbers/pycounts_tt_2024>"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down

0 comments on commit 5603ca8

Please sign in to comment.