Skip to content

Documentation - - refs/heads/main #760

Documentation - - refs/heads/main

Documentation - - refs/heads/main #760

name: Documentation
run-name: 'Documentation - ${{ inputs.oci-image-name }} - ${{ github.ref }}'
on:
push:
paths:
- "oci/*/documentation.y*ml"
branches:
- main
workflow_dispatch:
inputs:
oci-image-name:
description: 'OCI image to generate the documentation for'
required: true
external_ref_id: # (1)
description: 'Optional ID for unique run detection'
required: false
type: string
default: "default-id"
workflow_call:
inputs:
oci-image-name:
description: 'OCI image to generate the documentation for'
required: true
type: string
# Dry-run on PRs to generate a preview of the compiled documentation.
pull_request:
paths:
- "oci/*/documentation.y*ml"
jobs:
validate-documentation-request:
runs-on: ubuntu-22.04
name: Validate documentation request
outputs:
oci-img-path: ${{ steps.validate-image.outputs.img-path }}
oci-img-name: ${{ steps.validate-image.outputs.img-name }}
steps:
- name: ${{ inputs.external_ref_id }} # (2)
if: ${{ github.event_name == 'workflow_dispatch' }}
run: echo "Started by ${INPUTS_EXTERNAL_REF_ID}" >> "$GITHUB_STEP_SUMMARY"
env:
INPUTS_EXTERNAL_REF_ID: ${{ inputs.external_ref_id }}
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
persist-credentials: false
- name: Validate access to triggered image
uses: ./.github/actions/validate-actor
if: ${{ github.repository == 'canonical/oci-factory' && !github.event.pull_request.head.repo.fork }}
with:
admin-only: true
image-path: "oci/${{ inputs.oci-image-name }}"
github-token: ${{ secrets.ROCKSBOT_TOKEN }}
- name: Infer images to document
uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323
id: changed-files
if: github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call'
with:
dir_names: "true"
separator: ","
files: |
oci/*/documentation.y*ml
- name: Validate image from dispatch
id: validate-image
run: |
set -e
if [[ "$RUNNER_DEBUG" == "1" ]]; then
set -x
fi
source src/shared/logs.sh
# check if this is coming from a workflow dispatch/call
# as checking github.event_name isn't reliable here
if [ "${INPUTS_OCI_IMAGE_NAME}" != "" ]
then
img_path="oci/${INPUTS_OCI_IMAGE_NAME}"
else
img_path="${STEPS_CHANGED_FILES_OUTPUTS_ALL_CHANGED_FILES}"
occurrences="${img_path//[^,]}"
if [ ${#occurrences} -ne 0 ]
then
log_error "can only build documentation for 1 image at a time, but trying to document ${img_path}"
exit 1
fi
fi
test -d "${img_path}"
echo "img-name=$(basename ${img_path})" >> "$GITHUB_OUTPUT"
echo "img-path=${img_path}" >> "$GITHUB_OUTPUT"
env:
INPUTS_OCI_IMAGE_NAME: ${{ inputs.oci-image-name }}
STEPS_CHANGED_FILES_OUTPUTS_ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
do-documentation:
runs-on: ubuntu-22.04
name: Documentation
needs: [validate-documentation-request]
env:
IS_PROD: ${{ ! startsWith(needs.validate-documentation-request.outputs.oci-img-name, 'mock-') }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
persist-credentials: false
# This is needed to ensure that this workflow can run when called by workflows in external repositories
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
repository: canonical/oci-factory
path: oci-factory
persist-credentials: false
- name: Fetch _releases.json
uses: ./oci-factory/.github/actions/fetch-releases-json
with:
image-name: ${{ needs.validate-documentation-request.outputs.oci-img-name }}
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
with:
python-version: "3.x"
- name: Setup environment
run: pip install -r ./src/image/requirements.txt -r ./src/docs/requirements.txt
- name: Generate documentation for ${{ needs.validate-documentation-request.outputs.oci-img-name }}
id: generate-documentation
env:
ECR_CREDS_USR: ${{ env.IS_PROD == 'true' && secrets.ECR_CREDS_USR || secrets.ECR_CREDS_USR_DEV }}
ECR_CREDS_PSW: ${{ env.IS_PROD == 'true' && secrets.ECR_CREDS_PSW || secrets.ECR_CREDS_PSW_DEV }}
ECR_NAMESPACE: ${{ env.IS_PROD == 'true' && 'ubuntu' || secrets.ECR_NAMESPACE_DEV }}
DRY_RUN_FLAG: ${{ github.event_name == 'pull_request' && '--dry-run' || '' }}
NEEDS_VALIDATE_DOCUMENTATION_REQUEST_OUTPUTS_OCI_IMG_PATH: ${{ needs.validate-documentation-request.outputs.oci-img-path }}
run: |
set -e
if [[ "$RUNNER_DEBUG" == "1" ]]; then
set -x
fi
python3 -m src.docs.generate_oci_doc_yaml \
--ecr-api-key "${ECR_CREDS_USR}" \
--ecr-api-secret "${ECR_CREDS_PSW}" \
--oci-image-path "${NEEDS_VALIDATE_DOCUMENTATION_REQUEST_OUTPUTS_OCI_IMG_PATH}" \
--repository "${ECR_NAMESPACE}" \
--doc-data-dir data \
${DRY_RUN_FLAG:+${DRY_RUN_FLAG}}
- name: Upload documentation data YAML
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
with:
name: '${{ needs.validate-documentation-request.outputs.oci-img-name }}-doc-data'
path: "${{ steps.generate-documentation.outputs.image_doc_folder }}/*.y*ml"
if-no-files-found: error
- name: Publish Documentation for ${{ needs.validate-documentation-request.outputs.oci-img-name }}
env:
# In Dev, images go into the personal space of DOCKER_HUB_CREDS_USR_DEV
# so we can reuse its username (with a more privileged PAT) for updating the docs.
# In Prod, however, since it's an org, the collaborating DH account is different to
# segregate access and ensure other jobs in this pipeline don't abuse the privileged
# access that is needed here, for updating the docs.
DOCKER_HUB_CREDS_PSW_DOC: ${{ env.IS_PROD == 'true' && secrets.DOCKER_HUB_CREDS_PSW_DOC || secrets.DOCKER_HUB_CREDS_PSW_DOC_DEV }}
DOCKER_HUB_CREDS_USR_DOC: ${{ env.IS_PROD == 'true' && secrets.DOCKER_HUB_CREDS_USR_DOC || secrets.DOCKER_HUB_CREDS_USR_DEV }}
ECR_CREDS_USR: ${{ env.IS_PROD == 'true' && secrets.ECR_CREDS_USR || secrets.ECR_CREDS_USR_DEV }}
ECR_CREDS_PSW: ${{ env.IS_PROD == 'true' && secrets.ECR_CREDS_PSW || secrets.ECR_CREDS_PSW_DEV }}
ECR_REGISTRY_ID: ${{ env.IS_PROD == 'true' && secrets.ECR_REGISTRY_ID || secrets.ECR_REGISTRY_ID_DEV }}
DOCKER_HUB_NAMESPACE: ${{ env.IS_PROD == 'true' && 'docker.io/ubuntu' || secrets.DOCKER_HUB_NAMESPACE_DEV }}
DRY_RUN: ${{ github.event_name == 'pull_request' && 'true' || 'false' }}
NEEDS_VALIDATE_DOCUMENTATION_REQUEST_OUTPUTS_OCI_IMG_NAME: ${{ needs.validate-documentation-request.outputs.oci-img-name }}
STEPS_GENERATE_DOCUMENTATION_OUTPUTS_NAME_DOC_FILE: ${{ steps.generate-documentation.outputs.name_doc_file }}
STEPS_GENERATE_DOCUMENTATION_OUTPUTS_IMAGE_DOC_FOLDER: ${{ steps.generate-documentation.outputs.image_doc_folder }}
run: |
set -e
if [[ "$RUNNER_DEBUG" == "1" ]]; then
set -x
fi
./src/docs/publish_docs.sh "${NEEDS_VALIDATE_DOCUMENTATION_REQUEST_OUTPUTS_OCI_IMG_NAME}" "${STEPS_GENERATE_DOCUMENTATION_OUTPUTS_NAME_DOC_FILE}" "${STEPS_GENERATE_DOCUMENTATION_OUTPUTS_IMAGE_DOC_FOLDER}"
- name: Write documentation preview to summary
if: ${{ github.event_name == 'pull_request' }}
run: |
echo "# Preview for ${NEEDS_VALIDATE_DOCUMENTATION_REQUEST_OUTPUTS_OCI_IMG_NAME}" >> "$GITHUB_STEP_SUMMARY"
cat "${STEPS_GENERATE_DOCUMENTATION_OUTPUTS_IMAGE_DOC_FOLDER}/doc-preview.md" >> "$GITHUB_STEP_SUMMARY"
env:
NEEDS_VALIDATE_DOCUMENTATION_REQUEST_OUTPUTS_OCI_IMG_NAME: ${{ needs.validate-documentation-request.outputs.oci-img-name }}
STEPS_GENERATE_DOCUMENTATION_OUTPUTS_IMAGE_DOC_FOLDER: ${{ steps.generate-documentation.outputs.image_doc_folder }}
notify:
runs-on: ubuntu-22.04
name: Notify on failure
needs: [validate-documentation-request, do-documentation]
if: ${{ !cancelled() && contains(needs.*.result, 'failure') && github.event_name != 'workflow_dispatch' && github.event_name != 'pull_request' }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
persist-credentials: false
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
with:
python-version: '3.x'
- run: pip install -r src/notifications/requirements.txt
- name: Summarize workflow failure message
id: get-summary
run: |
echo '${{ toJson(needs) }}' > jobs.json
python3 -m src.notifications.mattermost_notifier summarize jobs.json
- name: Get contacts for ${{ needs.validate-documentation-request.outputs.oci-img-name }}
id: get-contacts
working-directory: ${{ needs.validate-documentation-request.outputs.oci-img-path }}
run: |
mm_channels=$(yq -r '.notify | ."mattermost-channels" | join(",")' < contacts.y*ml)
echo "mattermost-channels=${mm_channels}" >> "$GITHUB_OUTPUT"
- name: Notify via Mattermost
env:
MM_BOT_TOKEN: ${{ secrets.MM_BOT_TOKEN }}
FINAL_STATUS: failure
MM_SERVER: ${{ secrets.MM_SERVER }}
URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
SUMMARY: ${{ steps.get-summary.outputs.summary }}
FOOTER: "Triggered by ${{ github.triggering_actor }}. Ref: ${{ github.ref }}. Attempts: ${{ github.run_attempt }}"
TITLE: '${{ needs.validate-documentation-request.outputs.oci-img-name }}: failed to generate docs'
STEPS_GET_CONTACTS_OUTPUTS_MATTERMOST_CHANNELS: ${{ steps.get-contacts.outputs.mattermost-channels }}
run: |
for channel in $(echo ${STEPS_GET_CONTACTS_OUTPUTS_MATTERMOST_CHANNELS} | tr ',' ' ')
do
MM_CHANNEL_ID="${channel}" python3 -m src.notifications.mattermost_notifier send
done