Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
73cfed3
Restore for branch
May 6, 2024
641995d
Fix action name
May 6, 2024
c608ef9
Add bogus key
May 6, 2024
89b2020
Spec path
May 6, 2024
239aee1
Set cond
May 6, 2024
9a4ff47
Fix synt
May 6, 2024
c602a55
Simplify
May 6, 2024
fdb0f47
Merge branch 'main' into feat/20/no-update-on-failure
Tom-van-Woudenberg May 7, 2024
871c086
Merge branch 'main' into feat/20/no-update-on-failure
Tom-van-Woudenberg May 7, 2024
9a9edc4
Merge branch 'main' into feat/20/no-update-on-failure
Tom-van-Woudenberg May 7, 2024
adb272f
Attempt show status
May 9, 2024
6693bf1
Synt
May 9, 2024
90488c8
Simplify
May 9, 2024
1b43b76
Debug
May 9, 2024
19cdbc7
Debug 2
May 9, 2024
a31c7e2
Debug 3
May 9, 2024
05edbc6
Condition on partial cache hit
May 9, 2024
55a65db
Debug
May 9, 2024
d3fbb80
Refactor
May 9, 2024
be7eca8
Fix cond
May 9, 2024
8cd45e6
Name
May 9, 2024
79d01a7
Spec dir
May 9, 2024
65a4062
Spec .txt file
May 9, 2024
c151600
Add col
May 9, 2024
be41b47
Add legend
May 9, 2024
1d18453
Fix legend
May 9, 2024
4aae492
Debug
May 9, 2024
159ae6b
Debug
May 9, 2024
38ec331
Debug
May 9, 2024
938ccb5
Reuse branches var
May 10, 2024
986fc65
Synt
May 10, 2024
f1aa32a
Attempt workaround
May 10, 2024
eaa255e
Fix
May 10, 2024
8c336c4
Include status for aliases
May 10, 2024
a3d8d34
Debug
May 10, 2024
4771359
Fix
May 10, 2024
98b4ded
Fix
May 10, 2024
79b25e8
Attempt del aux artifacts
May 16, 2024
e538496
Add msg for primary branch
May 16, 2024
99567b2
Attempt expansion Q flag
May 16, 2024
82e8df6
Fix
May 16, 2024
eacd26d
Simplify
May 16, 2024
85c5054
Attempt fix aliases table
May 16, 2024
a773171
Add col
May 16, 2024
ed0d7e2
Update README.md
Tom-van-Woudenberg May 22, 2024
916938a
Set documentation to have one alias only
Tom-van-Woudenberg May 22, 2024
880fdf1
Update README with one alias
Tom-van-Woudenberg May 22, 2024
e79818e
no aliases defined by default
Tom-van-Woudenberg May 22, 2024
54e9f0c
Fix typo
Tom-van-Woudenberg May 22, 2024
715dcc7
typo fix
Tom-van-Woudenberg May 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 118 additions & 56 deletions .github/workflows/deploy-book.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# `main` as primary by default, advised to make it `published` to start using draft-publish-workflow
PRIMARY_BRANCH: ${{ vars.PRIMARY_BRANCH != '' && vars.PRIMARY_BRANCH || 'main' }}
# Space-separated list of alias-rules, e.g. 'draft:main alias:really-long-branch-name'
# By default, `draft` links to `main`. Advised to link `book` to `publish`
# If no aliases are wanted, BRANCH_ALIASES may be set to ' ' (space).
# alias-rule, e.g. 'draft:main'
# By default, no aliases are defined ('').
# If no alias is wanted, BRANCH_ALIASES may be set to ' ' (space).
BRANCH_ALIASES: ${{ vars.BRANCH_ALIASES }}
# Space-separated list of branch names, e.g. 'main second third'.
# By default, deploy all branches. This is indicated by '*'.
Expand All @@ -30,7 +30,6 @@ jobs:
runs-on: ubuntu-latest
outputs:
branches: ${{ steps.set-branches.outputs.branches }}
summary: ${{ steps.output-summary.outputs.summary }}
permissions:
contents: read
steps:
Expand All @@ -49,32 +48,8 @@ jobs:
branches=$(echo "$BRANCHES_TO_DEPLOY" | tr ' ' '\n' | grep -E '\S')
fi

{
# Display raw/clean branch name versions in Actions Summary
echo "### Branches deployed"
## Table headers
echo "| Branch :tanabata_tree: | Link :link: |"
echo "| :--- | :--- |"
} >> summary.md

## Fetch the GH Pages URL
# https://stackoverflow.com/a/76354104
url=$(gh api "repos/$GITHUB_REPOSITORY/pages" --jq '.html_url')

# Clean branch names
echo "$branches" > raw.txt
echo "$branches" | tr '/":<>|*?\/\\' '-' > clean.txt
paste -d ' ' raw.txt clean.txt |
while IFS=' ' read -r raw clean; do
echo "| $raw | <$url$clean> |" >> summary.md
done

{
# Primary branch
echo
echo '#### Primary book at root'
echo "The book published at the website root <$url> is from the primary branch \\\`$PRIMARY_BRANCH\\\`."
} >> summary.md
# Record branch names (one per line) for alias validation
echo "$branches" | tr ' ' '\n' > branches.txt

# Convert to a JSON list
branches=$(echo "$branches" | jq -Rn '[inputs]')
Expand All @@ -83,7 +58,6 @@ jobs:
- name: Validate aliases
run: |
# Prepare data
mv raw.txt branches.txt
echo "$BRANCH_ALIASES" | tr ' ' '\n' > rules.txt
cut -d: -f1 rules.txt > aliases.txt
cut -d: -f2 rules.txt > targets.txt
Expand Down Expand Up @@ -114,16 +88,6 @@ jobs:
exit 1
fi

# https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#example-of-a-multiline-string
- name: Output summary
id: output-summary
run: |
{
echo 'summary<<EOF'
cat summary.md
echo EOF
} >> "$GITHUB_OUTPUT"


build-books:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -161,7 +125,7 @@ jobs:
uses: actions/cache@v4
with:
path: "book/_build/html"
key: html-build-${{ hashFiles('book/**', 'requirements.txt', 'EXTRA_CACHE_VARS.txt') }}
key: html-build-${{ matrix.branch }}-${{ hashFiles('book/**', 'requirements.txt', 'EXTRA_CACHE_VARS.txt') }}

- if: ${{ steps.cache-html.outputs.cache-hit != 'true' }}
name: Set up Python 3.11
Expand Down Expand Up @@ -199,6 +163,38 @@ jobs:
teachbooks build $option_publish book/ > >(tee stdout.log) 2> >(tee stderr.log >&2)
set +o pipefail

- name: If failed, restore a book for this branch from cache
if: failure()
id: attempt-restore
uses: actions/cache/restore@v4
with:
key: none
path: "book/_build/html"
restore-keys: html-build-${{ matrix.branch }}

- name: Debug cache attempt output
if: failure()
run: |
echo cache-hit: ${{ steps.attempt-restore.outputs.cache-hit }}
echo cache-primary-key: ${{ steps.attempt-restore.outputs.cache-primary-key }}
echo cache-matched-key: ${{ steps.attempt-restore.outputs.cache-matched-key }}

- name: Record build failure
if: failure()
run: |
if [ -z "${{ steps.attempt-restore.outputs.cache-matched-key }}" ]; then
# Cache miss
echo ":o: \\\`Build failed [2]\\\`" | tee buildstatus.txt
else
# (Partial) cache hit
echo ":red_circle: \\\`Build failed [1]\\\`" | tee buildstatus.txt
fi

- name: Record build success
if: success()
run: |
echo ":white_check_mark: \\\`Published\\\`" >> buildstatus.txt

- name: Make summary of errors, if any
# run even in case of failure
if: always()
Expand Down Expand Up @@ -226,7 +222,15 @@ jobs:
name: _summary-${{ env.MATRIX_BRANCH_NAME_CLEAN }}
path: "summary.md"

- name: Upload build status as an artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: _buildstatus-${{ env.MATRIX_BRANCH_NAME_CLEAN }}
path: "buildstatus.txt"

- name: Upload the built book HTML as an artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: ${{ env.MATRIX_BRANCH_NAME_CLEAN }}
Expand All @@ -235,7 +239,9 @@ jobs:
deploy-books:
# Run after build-books, even if it failed
if: always()
needs: build-books
needs:
- get-branches
- build-books
outputs:
summary: ${{ steps.output-summary.outputs.summary }}
runs-on: ubuntu-latest
Expand All @@ -248,15 +254,27 @@ jobs:
- run: |
mkdir final/

- name: Download all book artifacts
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: "final/"

- name: Extract summaries from the downloaded artifacts
- name: Extract extras from the downloaded artifacts
run: |
mkdir _summaries/
mkdir _buildstatus/
mv final/_summary-* _summaries
mv final/_buildstatus-* _buildstatus

- name: Clean artifacts (1)
uses: GeekyEggo/delete-artifact@v5.0.0
with:
name: "_summary-*"

- name: Clean artifacts (2)
uses: GeekyEggo/delete-artifact@v5.0.0
with:
name: "_buildstatus-*"

- name: Copy primary book to root, fail if names conflict
timeout-minutes: 1
Expand All @@ -268,30 +286,72 @@ jobs:
fi
ls -a final/

- name: Include overview summary
run: |
# Restore "raw" branch names
echo '${{ needs.get-branches.outputs.branches }}' | jq -r '.[]' > raw.txt
{
# Display raw/clean branch name versions in Actions Summary
echo "### Branches deployed"
## Table headers
echo "| Branch :tanabata_tree: | Link :link: | Build status :ballot_box_with_check:"
echo "| :--- | :--- | :--- |"
} >> summary.md

## Fetch the GH Pages URL
# https://stackoverflow.com/a/76354104
url=$(gh api "repos/$GITHUB_REPOSITORY/pages" --jq '.html_url')

# Clean branch names
cat raw.txt | tr '/":<>|*?\/\\' '-' > clean.txt
cat clean.txt | xargs -I{} cat _buildstatus/_buildstatus-{}/buildstatus.txt > status.txt
paste -d ' ' raw.txt clean.txt status.txt > pasted.txt
cat pasted.txt |
while IFS=' ' read -r raw clean status; do
echo "| $raw | <$url$clean> | $status |" >> summary.md
done

primary_status=$(grep "^$PRIMARY_BRANCH " pasted.txt | cut -d\ -f4)

{
echo
echo "#### Legend for build status"
echo ":white_check_mark: \\\`Published\\\` - build success, new version published."
echo ":red_circle: \\\`Build failed [1]\\\` - build failure, previous version of the book reused."
echo ":o: \\\`Build failed [2]\\\` - build failure, no previous version reused."

echo
echo '#### Primary book at root'
echo "The book at the website root <$url> is from the primary branch \\\`$PRIMARY_BRANCH\\\` (status: $primary_status)."
} >> summary.md

- name: Symlink branch aliases
id: symlink-aliases
run: |
{
echo "### Aliases"
if echo "$BRANCH_ALIASES" | grep -E '\S'; then
echo "### Aliases" >> summary.md
if echo "$BRANCH_ALIASES" | grep -E '\S'; then
# Summary table headers
echo "| Alias :arrow_right: | Target :dart: | Link :link:"
echo "| :--- | :--- | :--- |"
else
echo "No aliases defined."
fi
} >> summary.md
{
echo "| Alias :arrow_right: | Target :dart: | Link :link: | Build status :ballot_box_with_check: |"
echo "| :--- | :--- | :--- | :--- |"
} >> summary.md
else
echo "No aliases defined." >> summary.md
fi

url=$(gh api "repos/$GITHUB_REPOSITORY/pages" --jq '.html_url')

paste -d ' ' clean.txt status.txt > lookup_status.txt

echo "$BRANCH_ALIASES" | tr ' ' '\n' | grep -E '\S' |
while IFS=':' read -r key value; do
# If the target branch is to be deployed, make symlink to it.
if [ "$BRANCHES_TO_DEPLOY" == "*" ] || echo "$BRANCHES_TO_DEPLOY" | tr ' ' '\n' | grep "^$value$"; then
# Clean branch names of special characters
clean_key=$(echo "$key" | tr '/":<>|*?\/\\' '-')
clean_value=$(echo "$value" | tr '/":<>|*?\/\\' '-')
echo "| $clean_key | $clean_value | <$url$clean_key> |" >> summary.md
status=$(grep "^$clean_value " lookup_status.txt | cut -d\ -f2,3)
echo "| $clean_key | $clean_value | <$url$clean_key> | $status |" >> summary.md
ln -s "$clean_value" final/"$key"
fi
done
Expand Down Expand Up @@ -325,6 +385,7 @@ jobs:
id: deployment
uses: actions/deploy-pages@v4

# source: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#example-of-a-multiline-string
- name: Output summary
id: output-summary
run: |
Expand All @@ -341,7 +402,8 @@ jobs:
- deploy-books
runs-on: ubuntu-latest
steps:
- run: |
- name: Summarize
run: |

echo "${{ needs.get-branches.outputs.summary }}" >> $GITHUB_STEP_SUMMARY
echo "${{ needs.deploy-books.outputs.summary }}" >> $GITHUB_STEP_SUMMARY
Expand Down
42 changes: 27 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ We developed a workflow which builds the Jupyter Books in your repository for al
It has the following features:
- Publishing of your [Jupyter Book](https://github.com/executablebooks/jupyter-book)-repository to GitHub Pages
- Publishing all or a selection of branches, allowing to build draft version of the book online preventing local builds
- A summary describing where the book is published, errors in the build process and how the publish step is configured
- A summary describing where the book is published, errors in the build process per branch and how the publish step is configured
- Caching of build books so that it can be reused when another branch is published or the next build contains critical errors
- Caching of python environment to speed up the workflow
- Allowing to use submodules within your book
- Customizable trigger for the workflow itself
- Optionally preprocess branches using the [`teachbooks` package](https://github.com/TeachBooks/TeachBooks).
- Converting branch-names to well-defined URLs
- Customizable settings on where the books should be deployed including alias for branch-names and selection of one branch to be deployed on root. The workflow will gives warnings if these setting are ill-defined or conflicting.
- Customizable settings on where the books should be deployed including alias for branch-names and selection of one branch to be deployed on root. The workflow will gives warnings if these setting are ill-defined or conflicting. Although aliases are not allowed by GitHub Pages, it seems you can use one alias, but not more.

The [TeachBooks template book](https://github.com/TeachBooks/template) uses this functionality for example: The workflow `call-deploy-book.yml` calls the `deploy-book.yml` workflow, which builds the Jupyter books at the calling repository for all branches, and deploys them via GitHub Pages.

Expand All @@ -31,11 +31,10 @@ You can adapt the behaviour by setting repository variables as explained [here](
- `PRIMARY_BRANCH` which is set to `main` whenever it's not defined in the repository variables.
- This sets the branch which is hosted on root.
- It is advised to make it `published` to start using draft-publish-workflow
- `BRANCH_ALIASES` which is set to `draft:main` whenever it's not defined in the repository variables.
- This defines aliases for branches
- It should be a space-separated list of alias-rules, e.g. 'draft:main alias:really-long-branch-name`
- It is advised to link `book` to `publish`.
- If no aliases are wanted, `BRANCH_ALIASES` may be set to ' ' (space).
- `BRANCH_ALIASES` which is set to ` `(space) whenever it's not defined in the repository variables.
- This defines an alias for a branch
- It should be an alias-rule, e.g. 'alias:really-long-branch-name`
- If no alias is wanted, `BRANCH_ALIASES` may be set to ' ' (space).
- `BRANCHES_TO_DEPLOY` which is set to `*` (all branches) whenever it's not defined in the repository variables.
- This defines the branches to deploy.
- It should be a space-separated list of branch names, e.g. 'main second third'.
Expand All @@ -57,18 +56,26 @@ Whenever the workflow is triggered, progress and a summary can be seen under the
Here's an example for a summary for the template book:

> ### Branches deployed
> | Branch 🎋 | Link 🔗 |
> | --- | --- |
> | main | [https://teachbooks.github.io/template/main](https://teachbooks.github.io/template/main) |
> | version2 | [https://teachbooks.github.io/template/version2](https://teachbooks.github.io/template/version2) |
> | Branch 🎋 | Link 🔗 | Build status ☑️ |
> | :--- | :--- | :--- |
> | main | [https://teachbooks.github.io/template/main](https://teachbooks.github.io/template/main) | ✅ `Published` |
> | version2 | [https://teachbooks.github.io/template/version2](https://teachbooks.github.io/template/version2) | 🔴 `Build failed [1]` |
> | version3 | [https://teachbooks.github.io/template/version3](https://teachbooks.github.io/template/version3) | ⭕ `Build failed [2]` |
>
> #### Legend for build status
> ✅ `Published` - build success, new version published.
>
> 🔴 `Build failed [1]` - build failure, previous version of the book reused.
>
> ⭕ `Build failed [2]` - build failure, no previous version reused.
>
> #### Primary book at root
> The book published at the website root [https://teachbooks.github.io/template](https://teachbooks.github.io/template) is from the primary branch `main`.
> The book at the website root <https://teachbooks.github.io/testable-template/> is from the primary branch `main` (status: `Published`).
>
> ### Aliases
> | Alias ➡️ | Target 🎯 | Link 🔗 |
> | --- | --- | --- |
> | draft | main | [https://teachbooks.github.io/template/draft](https://teachbooks.github.io/template/draft) |
> | Alias ➡️ | Target 🎯 | Link 🔗 | Build status ☑️ |
> | :--- | :--- | :--- | :---- |
> | draft | main | [https://teachbooks.github.io/template/draft](https://teachbooks.github.io/template/draft) | ✅ `Published` |
>
> ### Preview of build errors & warnings
> For more details please see the corresponding `build-books` jobs in the left pane.
Expand All @@ -78,6 +85,11 @@ Here's an example for a summary for the template book:
> �[91m/home/runner/work/template/template/book/some_content/overview.md:5: WARNING: Non-consecutive header level increase; H1 to H3 [myst.header]�[39;49;00m
> ```
>
> On branch `version3`:
> ```
> /home/runner/work/_temp/ff8c8325-8d8b-4c0b-a2b2-32d2169c55bc.sh: line 8: teachbooks: command not found
> ```
>
> ### Repository configuration variables
> Variables can be set at [https://github.com/TeachBooks/template/settings/variables/actions](https://github.com/TeachBooks/template/settings/variables/actions)
>
Expand Down