diff --git a/.github/workflows/build-book.yaml b/.github/workflows/build-book.yaml new file mode 100644 index 000000000..d9341b110 --- /dev/null +++ b/.github/workflows/build-book.yaml @@ -0,0 +1,77 @@ +name: build-book + +on: + workflow_call: + inputs: + environment_name: + description: 'Name of conda environment to activate' + required: false + default: 'cookbook-dev' + type: string + environment_file: + description: 'Name of conda environment file' + required: false + default: 'environment.yml' + type: string + path_to_notebooks: + description: 'Location of the JupyterBook source relative to repo root' + required: false + default: './' + type: string + use_cached_environment: + description: 'Flag for whether we should attempt to retrieve a previously cached environment.' + required: false + default: 'true' + type: string # had a lot of trouble with boolean types, see https://github.com/actions/runner/issues/1483 + +jobs: + build-container: + runs-on: ubuntu-latest + steps: + - name: checkout files in repo + uses: actions/checkout@v3 + - name: remove Dockerfile + run: | + rm binder/Dockerfile + - name: update jupyter dependencies with repo2docker + uses: jupyterhub/repo2docker-action@master + with: + DOCKER_USERNAME: "openradar" + DOCKER_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + DOCKER_REGISTRY: "ghcr.io" + PUBLIC_REGISTRY_CHECK: true + APPENDIX_FILE: "binder/appendix.txt" + REPO2DOCKER_EXTRA_ARGS: --Repo2Docker.base_image=docker.io/library/buildpack-deps:bionic + FORCE_REPO2DOCKER_VERSION: jupyter-repo2docker==2022.02.0 + + build-book: + runs-on: ubuntu-latest + container: + image: ghcr.io/openradar/erad2024:latest + options: --user root + needs: [build-container] + defaults: + run: + shell: bash -l {0} + steps: + - uses: actions/checkout@v3 + - name: Build the book + run: | + # copy baltrad notebooks to book dir + cp -rp /home/jovyan/notebooks/baltrad* notebooks/. + cp -rp /home/jovyan/notebooks/pyart2baltrad* notebooks/. + install/nbstripout_notebooks.sh + jupyter-book build ${{ inputs.path_to_notebooks }} + - name: Zip the book + run: | + set -x + set -e + if [ -f book.zip ]; then + rm -rf book.zip + fi + zip -r book.zip ${{ inputs.path_to_notebooks }}/_build/html + - name: Upload zipped book artifact + uses: actions/upload-artifact@v3 + with: + name: book-zip-${{github.event.number}} + path: ./book.zip \ No newline at end of file diff --git a/.github/workflows/deploy-book.yaml b/.github/workflows/deploy-book.yaml new file mode 100644 index 000000000..6cd4fad63 --- /dev/null +++ b/.github/workflows/deploy-book.yaml @@ -0,0 +1,42 @@ +name: deploy-book + +on: + # Trigger the workflow on push to main branch + push: + branches: + - main + workflow_dispatch: + +jobs: + build: + uses: ./.github/workflows/build-book.yaml + with: + environment_name: cookbook-dev + environment_file: environment.yml + path_to_notebooks: ./ + + deploy: + needs: build + runs-on: ubuntu-latest + defaults: + run: + shell: bash -l {0} + steps: + - name: Download Artifact Book + uses: actions/download-artifact@v3 + with: + name: book-zip-${{ github.event.number }} + + - name: Unzip the book + run: | + rm -rf _build/html + unzip book.zip + rm -f book.zip + + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v3.9.3 + if: github.ref == 'refs/heads/main' + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: _build/html + keep_files: true # This preserves existing previews from open PRs \ No newline at end of file diff --git a/.github/workflows/deploy-preview.yaml b/.github/workflows/deploy-preview.yaml new file mode 100644 index 000000000..3c3e27db8 --- /dev/null +++ b/.github/workflows/deploy-preview.yaml @@ -0,0 +1,137 @@ +name: deploy-preview +on: + workflow_run: + workflows: + - trigger-book-build + types: + - requested + - completed + +jobs: + deploy: + runs-on: ubuntu-latest + defaults: + run: + shell: bash -l {0} + steps: + - uses: actions/checkout@v4 + - name: Fetch Repo Name + id: repo-name + run: echo "::set-output name=value::$(echo '${{ github.repository }}' | awk -F '/' '{print $2}')" # just the repo name, not owner + + - name: Set message value + run: | + echo "comment_message=πŸ‘‹ Thanks for opening this PR! The Cookbook will be automatically built with [GitHub Actions](https://github.com/features/actions). To see the status of your deployment, click below." >> $GITHUB_ENV + + - name: Find Pull Request + uses: actions/github-script@v6 + id: find-pull-request + with: + script: | + let pullRequestNumber = '' + let pullRequestHeadSHA = '' + core.info('Finding pull request...') + const pullRequests = await github.rest.pulls.list({owner: context.repo.owner, repo: context.repo.repo}) + for (let pullRequest of pullRequests.data) { + if(pullRequest.head.sha === context.payload.workflow_run.head_commit.id) { + pullRequestHeadSHA = pullRequest.head.sha + pullRequestNumber = pullRequest.number + break + } + } + core.setOutput('number', pullRequestNumber) + core.setOutput('sha', pullRequestHeadSHA) + if(pullRequestNumber === '') { + core.info( + `No pull request associated with git commit SHA: ${context.payload.workflow_run.head_commit.id}` + ) + } + else{ + core.info(`Found pull request ${pullRequestNumber}, with head sha: ${pullRequestHeadSHA}`) + } + + - name: Find preview comment + uses: peter-evans/find-comment@v2 + if: steps.find-pull-request.outputs.number != '' + id: fc + with: + issue-number: '${{ steps.find-pull-request.outputs.number }}' + comment-author: 'github-actions[bot]' + body-includes: '${{ env.comment_message }}' + + - name: Create preview comment + if: | + github.event.workflow_run.conclusion != 'success' + && steps.find-pull-request.outputs.number != '' + && steps.fc.outputs.comment-id == '' + uses: peter-evans/create-or-update-comment@v3 + with: + issue-number: ${{ steps.find-pull-request.outputs.number }} + body: | + ${{ env.comment_message }} + πŸ” Git commit SHA: ${{ steps.find-pull-request.outputs.sha }} + βœ… Deployment Preview URL: In Progress + + - name: Update preview comment + if: | + github.event.workflow_run.conclusion != 'success' + && steps.find-pull-request.outputs.number != '' + && steps.fc.outputs.comment-id != '' + uses: peter-evans/create-or-update-comment@v3 + with: + comment-id: ${{ steps.fc.outputs.comment-id }} + edit-mode: replace + body: | + ${{ env.comment_message }} + πŸ” Git commit SHA: ${{ steps.find-pull-request.outputs.sha }} + βœ… Deployment Preview URL: In Progress + + - name: Download Artifact Book + if: | + github.event.workflow_run.conclusion == 'success' + && steps.find-pull-request.outputs.number != '' + && steps.fc.outputs.comment-id != '' + uses: dawidd6/action-download-artifact@v2.27.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + workflow: build-book.yaml + run_id: ${{ github.event.workflow_run.id }} + name: book-zip-${{ steps.find-pull-request.outputs.number }} + + - name: Unzip the book + if: | + github.event.workflow_run.conclusion == 'success' + && steps.find-pull-request.outputs.number != '' + && steps.fc.outputs.comment-id != '' + run: | + rm -rf _build/html + unzip book.zip + rm -f book.zip + + # Push the book's HTML to github-pages + # This will be published at /_preview/PRnumber/ relative to the main site + - name: Deploy to GitHub pages + if: | + github.event.workflow_run.conclusion == 'success' + && steps.find-pull-request.outputs.number != '' + && steps.fc.outputs.comment-id != '' + uses: peaceiris/actions-gh-pages@v3.9.3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: _build/html + enable_jekyll: false + destination_dir: _preview/${{ steps.find-pull-request.outputs.number }} + + - name: Finalize preview comment + if: | + github.event.workflow_run.conclusion == 'success' + && steps.find-pull-request.outputs.number != '' + && steps.fc.outputs.comment-id != '' + uses: peter-evans/create-or-update-comment@v3 + with: + comment-id: ${{ steps.fc.outputs.comment-id }} + edit-mode: replace + body: | + ${{ env.comment_message }} + πŸ” Git commit SHA: ${{ steps.find-pull-request.outputs.sha }} + βœ… Deployment Preview URL: https://${{ github.repository_owner }}.github.io/${{ steps.repo-name.outputs.value }}/_preview/${{ steps.find-pull-request.outputs.number }} \ No newline at end of file diff --git a/.github/workflows/link-checker.yaml b/.github/workflows/link-checker.yaml new file mode 100644 index 000000000..72c34b1c8 --- /dev/null +++ b/.github/workflows/link-checker.yaml @@ -0,0 +1,58 @@ +name: link-checker + +on: + workflow_call: + inputs: + environment_name: + description: 'Name of conda environment to activate' + required: false + default: 'cookbook-dev' + type: string + environment_file: + description: 'Name of conda environment file' + required: false + default: 'environment.yml' + type: string + path_to_notebooks: + description: 'Location of the JupyterBook source relative to repo root' + required: false + default: './' + type: string + use_cached_environment: + description: 'Flag for whether we should attempt to retrieve a previously cached environment.' + required: false + default: 'true' + type: string + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + link-checker: + runs-on: ubuntu-latest + defaults: + run: + shell: bash -l {0} + steps: + - uses: actions/checkout@v4 + - name: Setup Micromamba + uses: mamba-org/setup-micromamba@v1 + with: + environment-name: ${{ inputs.environment_name }} + environment-file: ${{ inputs.environment_file }} + cache-environment: ${{ inputs.use_cached_environment }} + cache-environment-key: "linux-64-conda-${{ hashFiles('${{ inputs.environment_file }}') }}-${{ env.TODAY }}" + + - name: Disable notebook execution + shell: python + run: | + import yaml + with open('${{ inputs.path_to_notebooks }}/_config.yml') as f: + data = yaml.safe_load(f) + data['execute']['execute_notebooks'] = 'off' + with open('${{ inputs.path_to_notebooks }}/_config.yml', 'w') as f: + yaml.dump(data, f) + - name: Check external links + run: | + jupyter-book build --builder linkcheck ${{ inputs.path_to_notebooks }} \ No newline at end of file diff --git a/.github/workflows/publish-book.yaml b/.github/workflows/publish-book.yaml index cc1d1a4e2..74b2f3694 100644 --- a/.github/workflows/publish-book.yaml +++ b/.github/workflows/publish-book.yaml @@ -1,18 +1,21 @@ -name: publish-book +name: nightly-build on: - # Trigger the workflow on push to main branch - push: - branches: - - main workflow_dispatch: + schedule: + - cron: '0 0 * * *' # Daily β€œAt 00:00” jobs: build: - uses: ProjectPythia/cookbook-actions/.github/workflows/build-book.yaml@main + uses: ./.github/workflows/build-book.yaml with: environment_name: cookbook-dev + environment_file: environment.yml + path_to_notebooks: ./ - deploy: - needs: build - uses: ProjectPythia/cookbook-actions/.github/workflows/deploy-book.yaml@main + link-check: + uses: ./.github/workflows/link-checker.yaml + with: + environment_name: cookbook-dev + environment_file: environment.yml + path_to_notebooks: ./ \ No newline at end of file diff --git a/binder/Dockerfile b/binder/Dockerfile new file mode 100644 index 000000000..e93da14b7 --- /dev/null +++ b/binder/Dockerfile @@ -0,0 +1,3 @@ +FROM ghcr.io/openradar/erad2022:latest + +RUN mamba env update -f binder/environment.yml \ No newline at end of file diff --git a/binder/postBuild b/binder/postBuild new file mode 100644 index 000000000..186b20a86 --- /dev/null +++ b/binder/postBuild @@ -0,0 +1,18 @@ +sudo apt update +sudo wget -q -O /tmp/lrose.deb https://github.com/NCAR/lrose-core/releases/download/lrose-core-20240410/lrose-core-20240410.ubuntu_22.04.amd64.deb +sudo apt-get -y install /tmp/lrose.deb +sudo apt-get clean +sudo rm -rf /tmp/lrose.deb + +export CONDA_DIR=/srv/conda +export RADARENV=notebook +export CONDA_PREFIX=$CONDA_DIR/envs/$RADARENV +export PROJ_NETWORK=ON +export BALTRAD_INSTALL_ROOT=${PWD} +echo "export CONDA_DIR=$CONDA_DIR" >> ~/.profile && \ +echo "export RADARENV=$RADARENV" >> ~/.profile && \ +echo "export CONDA_PREFIX=$CONDA_PREFIX" >> ~/.profile && \ +echo "export PROJ_NETWORK=$PROJ_NETWORK" >> ~/.profile && \ +${CONDA_PREFIX}/bin/bash -l $BALTRAD_INSTALL_ROOT/install/baltrad/install_baltrad.sh && \ +${CONDA_PREFIX}/bin/bash -l $BALTRAD_INSTALL_ROOT/install/nbstripout_notebooks.sh && \ +cp binder/kernel.json $CONDA_PREFIX/share/jupyter/kernels/python3/.