From 06fa756b98f3a86254e3bd2cf2b17f2bd5829023 Mon Sep 17 00:00:00 2001 From: Darragh Bailey Date: Mon, 28 Aug 2023 20:41:36 +0100 Subject: [PATCH] Update publish docs workflows (#1762) Switch to standard workflow for building the documentation from pull requests and use a workflow call to trigger the deployment for write access. This should limit the ability to compromise documentation site from forked PRs while allow validation of dependency changes as well as more of the actions that impact the deploy. --- .github/workflows/build-docs/action.yml | 56 +++++++++ .../workflows/build-documentation-preview.yml | 39 ++++++ .github/workflows/deploy-docs-preview.yml | 116 ++++++++++++++++++ .github/workflows/deploy-docs.yml | 39 ++++++ .github/workflows/docker-image.yml | 4 + .github/workflows/integration-tests.yml | 4 + .../publish-documentation-preview-notify.yml | 25 ---- .../publish-documentation-preview.yml | 78 ------------ .../publish-documentation-release.yml | 35 +----- .github/workflows/publish-documentation.yml | 33 +---- .github/workflows/unit-tests.yml | 1 + 11 files changed, 266 insertions(+), 164 deletions(-) create mode 100644 .github/workflows/build-docs/action.yml create mode 100644 .github/workflows/build-documentation-preview.yml create mode 100644 .github/workflows/deploy-docs-preview.yml create mode 100644 .github/workflows/deploy-docs.yml delete mode 100644 .github/workflows/publish-documentation-preview-notify.yml delete mode 100644 .github/workflows/publish-documentation-preview.yml diff --git a/.github/workflows/build-docs/action.yml b/.github/workflows/build-docs/action.yml new file mode 100644 index 0000000..3be1d18 --- /dev/null +++ b/.github/workflows/build-docs/action.yml @@ -0,0 +1,56 @@ +name: Build Docs +inputs: + extra-config: + required: false + type: string + target-folder: + require: false + type: string + +runs: + using: composite + steps: + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.7 + + - name: Configure + shell: bash + env: + TARGET_FOLDER: ${{ inputs.target-folder }} + EXTRA_CONFIG: ${{ inputs.extra-config }} + run: | + [[ ${RUNNER_DEBUG:-0} -eq 1 ]] && set -x + + REPO_NAME=$(jq -r ".repository.name" "$GITHUB_EVENT_PATH") + + TEMP_CONFIG=$(mktemp) + # avoid look up of API as it doesn't work from within actions without exposing the GITHUB_TOKEN here which is a security risk + cat <> ${TEMP_CONFIG} + repository_nwo: ${GITHUB_REPOSITORY} + EOF + + if [[ -n "${TARGET_FOLDER}" ]] + then + echo "baseurl: /${REPO_NAME}/${TARGET_FOLDER}" >> ${TEMP_CONFIG} + fi + + # allow override of everything + cat <> ${TEMP_CONFIG} + ${EXTRA_CONFIG} + EOF + + echo "Adding additional config settings:" + cat ${TEMP_CONFIG} | tee docs/_config.yml + + - name: Install and Build + shell: bash + env: + BUNDLE_GEMFILE: ./docs/Gemfile + run: | + # TODO find a way for jekyll to perform this automatically + convert docs/_assets/images/logo.png -define icon:auto-resize=256,64,48,32,16 docs/favicon.ico + + bundle install + bundle exec jekyll build --source docs/ --destination build diff --git a/.github/workflows/build-documentation-preview.yml b/.github/workflows/build-documentation-preview.yml new file mode 100644 index 0000000..e3fe13c --- /dev/null +++ b/.github/workflows/build-documentation-preview.yml @@ -0,0 +1,39 @@ +name: Build Docs Preview +on: + pull_request: + types: + - closed + - opened + - reopened + - synchronize + paths: + - 'docs/**' + - '.github/workflows/build-documentation-preview.yml' + - '.github/workflows/build-docs/**' + +jobs: + build-docs: + runs-on: ubuntu-latest + steps: + - name: Checkout 🛎️ + uses: actions/checkout@v3 + + - name: Build docs 🔧 + if: github.event.action != 'closed' + uses: ./.github/workflows/build-docs + with: + target-folder: "pr-preview/pr-${{ github.event.number }}" + extra-config: | + plugin_script_base_path: "/${{ github.event.repository.name }}/pr-preview/pr-${{ github.event.number }}" + + - uses: actions/upload-artifact@v2 + if: github.event.action != 'closed' + with: + name: jekyll-docs + path: | + build/** + + - uses: actions/upload-artifact@v2 + with: + name: source-event + path: ${{ github.event_path }} diff --git a/.github/workflows/deploy-docs-preview.yml b/.github/workflows/deploy-docs-preview.yml new file mode 100644 index 0000000..bdbc8e9 --- /dev/null +++ b/.github/workflows/deploy-docs-preview.yml @@ -0,0 +1,116 @@ +name: Deploy Docs Preview +on: + workflow_run: + workflows: + - "Build Docs Preview" + types: + - completed + +permissions: + contents: write + pull-requests: write + +jobs: + deploy-preview: + concurrency: publish-gh-pages + runs-on: ubuntu-latest + if: github.event.workflow_run.event == 'pull_request' + steps: + - name: Checkout 🛎️ + uses: actions/checkout@v3 + + - name: 'Download artifact' + uses: dawidd6/action-download-artifact@v2 + with: + run_id: ${{github.event.workflow_run.id }} + + - name: Configure Settings + env: + SOURCE_EVENT_PATH: source-event/event.json + run: | + echo "Using ${SOURCE_EVENT_PATH} as event source" + + event_type=$(jq -r ".action" "$SOURCE_EVENT_PATH") + echo "event_type is $event_type" + case $event_type in + "opened" | "reopened" | "synchronize") + echo "action=deploy" >> $GITHUB_ENV + ;; + "closed") + echo "action=remove" >> $GITHUB_ENV + ;; + *) + echo "unknown event type $event_type; no action to take" + echo "action=none" >> $GITHUB_ENV + ;; + esac + + org=$(echo "$GITHUB_REPOSITORY" | cut -d "/" -f 1) + thirdleveldomain=$(echo "$GITHUB_REPOSITORY" | cut -d "/" -f 2) + + if [ ! -z "$customurl" ]; then + pagesurl="$customurl" + elif [ "${org}.github.io" == "$thirdleveldomain" ]; then + pagesurl="${org}.github.io" + else + pagesurl=$(echo "$GITHUB_REPOSITORY" | sed 's/\//.github.io\//') + fi + + echo "pagesurl=$pagesurl" >> $GITHUB_ENV + + echo "preview_branch=gh-pages" >> $GITHUB_ENV + + pr=$(jq -r ".number" "$SOURCE_EVENT_PATH") + echo "pr=${pr}" >> $GITHUB_ENV + echo "targetdir=pr-preview/pr-${pr}" >> $GITHUB_ENV + + echo "emptydir=$(mktemp -d)" >> $GITHUB_ENV + echo "datetime=$(date '+%Y-%m-%d %H:%M %Z')" >> $GITHUB_ENV + + - name: Deploy preview directory + if: env.action == 'deploy' + uses: JamesIves/github-pages-deploy-action@v4.4.1 + with: + branch: ${{ env.preview_branch }} + folder: jekyll-docs + target-folder: ${{ env.targetdir }} + commit-message: Deploy preview for PR ${{ env.pr }} 🛫 + force: false + + - name: Leave a comment after deployment + if: env.action == 'deploy' && env.deployment_status == 'success' + uses: marocchino/sticky-pull-request-comment@v2 + with: + number: ${{ env.pr }} + header: pr-preview + message: "\ + :rocket: Deployed preview to + https://${{ env.pagesurl }}/${{ env.targetdir }}/ + + on branch [`${{ env.preview_branch }}`](\ + ${{ github.server_url }}/${{ github.repository }}\ + /tree/${{ env.preview_branch }}) + at ${{ env.datetime }} + " + + - name: Remove preview directory + if: env.action == 'remove' + uses: JamesIves/github-pages-deploy-action@v4.4.1 + with: + branch: ${{ env.preview_branch }} + folder: ${{ env.emptydir }} + target-folder: ${{ env.targetdir }} + commit-message: Remove preview for PR ${{ env.pr }} 🛬 + force: false + + - name: Leave a comment after removal + if: env.action == 'remove' && env.deployment_status == 'success' + uses: marocchino/sticky-pull-request-comment@v2 + with: + number: ${{ env.pr }} + header: pr-preview + message: "\ + Preview removed because the pull request was closed. + + ${{ env.datetime }} + " diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml new file mode 100644 index 0000000..24020e5 --- /dev/null +++ b/.github/workflows/deploy-docs.yml @@ -0,0 +1,39 @@ +name: Deploy Docs +on: + workflow_call: + inputs: + extra-config: + required: false + type: string + target-folder: + require: false + type: string + +permissions: + contents: write + +jobs: + build-and-deploy: + concurrency: publish-gh-pages + runs-on: ubuntu-latest + steps: + - name: Checkout 🛎️ + uses: actions/checkout@v3 + + - name: Build Docs 🔧 + uses: ./.github/workflows/build-docs + with: + target-folder: ${{ inputs.target-folder }} + extra-config: ${{ inputs.extra-config }} + + - name: Deploy 🚀 + uses: JamesIves/github-pages-deploy-action@v4.4.1 + with: + branch: gh-pages + folder: build + force: false + target-folder: ${{ inputs.target-folder }} + clean-exclude: | + pr-preview/ + version/ + diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index fc861a0..58cfe6c 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -14,6 +14,10 @@ on: - reopened # for delete - closed + paths-ignore: + - 'docs/**' + - '.github/workflows/publish-documentation*' + - '.github/workflows/deploy-docs*' permissions: diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 4a1c5ba..4c49981 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -5,6 +5,10 @@ on: branches: - main pull_request: + paths-ignore: + - 'docs/**' + - '.github/workflows/publish-documentation*' + - '.github/workflows/deploy-docs*' jobs: generate-matrix: diff --git a/.github/workflows/publish-documentation-preview-notify.yml b/.github/workflows/publish-documentation-preview-notify.yml deleted file mode 100644 index 242cfc2..0000000 --- a/.github/workflows/publish-documentation-preview-notify.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Deploy Docs Preview Requires Label -on: - pull_request_target: - types: - - opened - - reopened - - synchronize - paths: - - 'docs/**' - -permissions: - pull-requests: write -jobs: - notify-label-required: - if: ${{ !contains(github.event.pull_request.labels.*.name, 'preview-docs') }} - runs-on: ubuntu-latest - steps: - - name: Comment on label required for docs preview deploy - uses: marocchino/sticky-pull-request-comment@v2 - with: - recreate: true - header: notify-label-required - message: |- - Maintainers: This PR updates the documentation, please review and apply - the label 'preview-docs' if satisfied it is safe to publish. diff --git a/.github/workflows/publish-documentation-preview.yml b/.github/workflows/publish-documentation-preview.yml deleted file mode 100644 index 31ecc62..0000000 --- a/.github/workflows/publish-documentation-preview.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: Deploy Docs Preview -on: - pull_request_target: - types: - - closed - - labeled - paths: - - 'docs/**' - -permissions: - contents: write - pull-requests: write -jobs: - build-and-deploy: - if: ${{ github.event.action == 'closed' || (github.event.action == 'labeled' && github.event.label.name == 'preview-docs') }} - concurrency: publish-gh-pages - runs-on: ubuntu-latest - steps: - - name: Checkout 🛎️ - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - - name: Set up Ruby - if: ${{ github.event.action == 'labeled' }} - uses: ruby/setup-ruby@v1 - with: - ruby-version: 2.7 - bundler-cache: true - env: - BUNDLE_GEMFILE: ./docs/Gemfile - - name: Install and Build 🔧 - # don't allow a close to execute anything from the source code - if: ${{ github.event.action == 'labeled' }} - run: | - PR_NUMBER=$(jq -r ".number" "$GITHUB_EVENT_PATH") - REPO_NAME=$(jq -r ".repository.name" "$GITHUB_EVENT_PATH") - - # TODO find a way for jekyll to perform this automatically - convert docs/_assets/images/logo.png -define icon:auto-resize=256,64,48,32,16 docs/favicon.ico - - # avoid look up of API as it doesn't work from within actions without exposing the GITHUB_TOKEN here which is a security risk - cat <> docs/_config.yml - repository_nwo: vagrant-libvirt/vagrant-libvirt - plugin_script_base_path: /${REPO_NAME}/pr-preview/pr-${PR_NUMBER} - EOF - - bundle exec jekyll build --source docs/ --baseurl="/${REPO_NAME}/pr-preview/pr-${PR_NUMBER}" --destination build - - name: Set action - run: | - event_type=$(jq -r ".action" "$GITHUB_EVENT_PATH") - echo "event_type is $event_type" - - case $event_type in - "labeled") - echo "action set to deploy" - echo "action=deploy" >> "$GITHUB_ENV" - ;; - "closed") - echo "action set to remove" - echo "action=remove" >> "$GITHUB_ENV" - ;; - *) - echo "unknown event type $event_type; no action to take" - echo "action=none" >> "$GITHUB_ENV" - ;; - esac - - name: Deploy preview - uses: rossjrw/pr-preview-action@v1 - with: - action: ${{ env.action }} - source-dir: ./build/ - preview-branch: gh-pages - umbrella-dir: pr-preview - - name: Remove label - uses: actions-ecosystem/action-remove-labels@v1 - if: ${{ always() }} - with: - labels: preview-docs diff --git a/.github/workflows/publish-documentation-release.yml b/.github/workflows/publish-documentation-release.yml index 80ab4b6..4d65a21 100644 --- a/.github/workflows/publish-documentation-release.yml +++ b/.github/workflows/publish-documentation-release.yml @@ -1,4 +1,4 @@ -name: Deploy Docs Release +name: Publish Docs Release on: push: tags: @@ -9,38 +9,9 @@ permissions: jobs: build-and-deploy: - concurrency: ci-${{ github.ref }} runs-on: ubuntu-latest steps: - - name: Checkout 🛎️ - uses: actions/checkout@v3 - - name: Set up Ruby - uses: ruby/setup-ruby@v1 + - name: Deploy docs + uses: ./.github/workflows/deploy-docs.yml with: - ruby-version: 2.7 - - name: Install and Build 🔧 - run: | - VERSION=${{ github.ref_name }} - REPO_NAME=$(jq -r ".repository.name" "$GITHUB_EVENT_PATH") - - # TODO find a way for jekyll to perform this automatically - convert docs/_assets/images/logo.png -define icon:auto-resize=256,64,48,32,16 docs/favicon.ico - - # avoid look up of API as it doesn't work from within actions without exposing the GITHUB_TOKEN here which is a security risk - cat <> docs/_config.yml - repository_nwo: vagrant-libvirt/vagrant-libvirt - EOF - - BUNDLE_GEMFILE=./docs/Gemfile bundle install - BUNDLE_GEMFILE=./docs/Gemfile bundle exec jekyll build --source docs/ --baseurl="/${REPO_NAME}/version/${VERSION}" --destination build - - name: Deploy 🚀 - uses: JamesIves/github-pages-deploy-action@v4.4.2 - with: - branch: gh-pages - folder: build - clean: true - force: false target-folder: version/${{ github.ref_name }} - clean-exclude: | - pr-preview/ - version/ diff --git a/.github/workflows/publish-documentation.yml b/.github/workflows/publish-documentation.yml index 22f5420..c21d697 100644 --- a/.github/workflows/publish-documentation.yml +++ b/.github/workflows/publish-documentation.yml @@ -1,43 +1,18 @@ -name: Deploy Docs +name: Publish Docs on: push: branches: - main paths: - 'docs/**' + - .github/workflows/publish-documentation.yml permissions: contents: write jobs: build-and-deploy: - concurrency: ci-${{ github.ref }} runs-on: ubuntu-latest steps: - - name: Checkout 🛎️ - uses: actions/checkout@v3 - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: 2.7 - - name: Install and Build 🔧 - run: | - # TODO find a way for jekyll to perform this automatically - convert docs/_assets/images/logo.png -define icon:auto-resize=256,64,48,32,16 docs/favicon.ico - - # avoid look up of API as it doesn't work from within actions without exposing the GITHUB_TOKEN here which is a security risk - cat <> docs/_config.yml - repository_nwo: vagrant-libvirt/vagrant-libvirt - EOF - - BUNDLE_GEMFILE=./docs/Gemfile bundle install - BUNDLE_GEMFILE=./docs/Gemfile bundle exec jekyll build --source docs/ --destination build - - name: Deploy 🚀 - uses: JamesIves/github-pages-deploy-action@v4.4.2 - with: - branch: gh-pages - folder: build - clean: true - clean-exclude: | - pr-preview/ - version/ + - name: Deploy docs + uses: ./.github/workflows/deploy-docs.yml diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 6e48928..8f4e967 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -118,6 +118,7 @@ jobs: }} - name: Coveralls Finished uses: coverallsapp/github-action@master + if: contains(needs.*.result, 'skipped') == false with: github-token: ${{ secrets.github_token }} parallel-finished: true