diff --git a/.github/workflows/PublishReleaseNotes.yml b/.github/workflows/PublishReleaseNotes.yml index f28e9f1..114c7e0 100644 --- a/.github/workflows/PublishReleaseNotes.yml +++ b/.github/workflows/PublishReleaseNotes.yml @@ -343,7 +343,7 @@ jobs: NOTES="${NOTES//%%gh_workflow_name%%/${{ github.workflow }}}" NOTES="${NOTES//%%gh_owner%%/${{ github.repository_owner }}}" NOTES="${NOTES//%%gh_repo%%/${repo}}" - NOTES="${NOTES//%%gh_owner_repo%%/${{ github.repository_owner }}}" + NOTES="${NOTES//%%gh_owner_repo%%/${{ github.repository }}}" #NOTES="${NOTES//%%gh_pages%%/https://${{ github.repository_owner }}.github.io/${repo}/}" NOTES="${NOTES//%%gh_runid%%/${{ github.run_id }}}" NOTES="${NOTES//%%gh_actor%%/${{ github.actor }}}" diff --git a/doc/JobTemplate/Release/PublishReleaseNotes.rst b/doc/JobTemplate/Release/PublishReleaseNotes.rst index f07a36e..f191378 100644 --- a/doc/JobTemplate/Release/PublishReleaseNotes.rst +++ b/doc/JobTemplate/Release/PublishReleaseNotes.rst @@ -3,11 +3,23 @@ PublishReleaseNotes ################### -This template runs ... +This template create a GitHub Release Page and uploads assets to that page. .. topic:: Features - * tbd + * Assembly a release description from various sources: + + * Description file in the repository. + * Description via job template parameter. + * Description from associated pull-request. + + * Download artifact and upload selected files as assets to the release page. + * Add an inventory file in JSON format as asset to each release. + * Replace placeholders with variable contents. + * Override the release's title. + * Create draft releases. + * Create pre-release release. + * Create nightly/rolling releases. .. topic:: Behavior @@ -37,7 +49,7 @@ This template runs ... * ``jq`` (JSON processing) * apt - zstd + * zstd .. _JOBTMPL/PublishReleaseNotes/Instantiation: @@ -48,9 +60,20 @@ Instantiation .. code-block:: yaml jobs: - Release: - uses: pyTooling/Actions/.github/workflows/Release.yml@r5 + Prepare: + uses: pyTooling/Actions/.github/workflows/PrepareJob.yml@r5 + Release: + uses: pyTooling/Actions/.github/workflows/PublishReleaseNotes.yml@r5 + needs: + - Prepare + if: needs.Prepare.outputs.is_release_tag == 'true' + permissions: + contents: write + actions: write + with: + tag: ${{ needs.Prepare.outputs.version }} + secrets: inherit .. seealso:: @@ -58,6 +81,139 @@ Instantiation ``TagReleaseCommit`` is +.. _JOBTMPL/PublishReleaseNotes/ReleaseNotes: + +Release Notes +************* + +Providing a release description (a.k.a release page content) can be achieved from various sources. These sources can +also be compined to a single description. Moreover, the resulting description can contain placeholders which can be +replaced by values provided via parameter :ref:`JOBTMPL/PublishReleaseNotes/Input/replacements`. + +Description text from file in the repository + The job template's parameter :ref:`JOBTMPL/PublishReleaseNotes/Input/description_file` provides a way to read a + predfined content from a file within the repository. This allows sharing the same text between nightly releases and + full releases. + + .. note:: + + This file can't be computed/modified at pipeline runtime, because a fixed Git commit is checked out for this job + template run. +Descriptions text from pipeline parameter + The job template's parameter :ref:`JOBTMPL/PublishReleaseNotes/Input/description` provides a way to either hard code + a release description in YAML code, or connect a GitHub Action variable ``${{ ... }}`` to that parameter. + + The content is avilable in replament variable ``%%DESCRIPTION%%``. +Description text from associated PullRequest + If an associated pull-request can be identified for a merge-commit, the pull-requests description can be used as a + release description. + + The content is avilable in replament variable ``%%PULLREQUEST%%``. +Additional text from :ref:`JOBTMPL/PublishReleaseNotes/Input/description_footer` + Additionally, a footer text is provided. + + The content is avilable in replament variable ``%%FOOTER%%``. + +.. topic:: Order of Processing + + 1. If :ref:`JOBTMPL/PublishReleaseNotes/Input/description_file` exists and is not empty, it will serve as the main + description. If the description contains ``%%...%%`` placeholders, these placeholders will be replaced + accordingly. If description contains ``%...%`` placeholders, replacement rules provided by + :ref:`JOBTMPL/PublishReleaseNotes/Input/replacements` will be applied. + 2. If :ref:`JOBTMPL/PublishReleaseNotes/Input/description` is not empty, it will serve as the main description. If + the description contains ``%%...%%`` placeholders, these placeholders will be replaced accordingly. If description + contains ``%...%`` placeholders, replacement rules provided by :ref:`JOBTMPL/PublishReleaseNotes/Input/replacements` + will be applied. + 3. If the associated pull-request exists and is not empty, it's description will serve as the main description. If + the description contains ``%%...%%`` placeholders, these placeholders will be replaced accordingly. If description + contains ``%...%`` placeholders, replacement rules provided by :ref:`JOBTMPL/PublishReleaseNotes/Input/replacements` + will be applied. + 4. Otherwise, an error is raised. + +.. topic:: Replacements + + ``%%DESCRIPTION%%`` + Replaces the placeholder with the content from :ref:`JOBTMPL/PublishReleaseNotes/Input/description`. + ``%%PULLREQUEST%%``, ``%%PULLREQUEST+0%%``, ``%%PULLREQUEST+1%%``, ``%%PULLREQUEST+2%%``, ``%%PULLREQUEST+3%%`` + Replaces the content by the associated pull-requests description text. + + If an indentation level +N (``+1``, ``+2``, ``+3``) is specified, headlines in the pull-request description will be + moved by N levels down. + ``%%FOOTER%%`` + Replaces the placeholder with the content from :ref:`JOBTMPL/PublishReleaseNotes/Input/description_footer`. + ``%%gh_server%%`` + Replaced by the GitHub server URL. |br| + The value is derived from ``${{ github.server_url }}``. + ``%%gh_workflow_name%%`` + Replaced by the workflow name. |br| + The value is derived from ``${{ github.workflow }}``. + ``%%gh_owner%%`` + Replaced by the repository owner, which is either the name of a GitHub organisation or a GitHub user account. |br| + The value is derived from ``${{ github.repository_owner }}``. + ``%%gh_repo%%`` + Replaced by the repository name. |br| + The value is derived from ``${{ github.repository }}`` by splitting namespace and repository name into the + ``${repo}`` variable. + ``%%gh_owner_repo%%`` + Replaced by the repository slug, which is either the name of a GitHub organisation or a GitHub user account + followed by the repository name concatenated by the slash character. |br| + The value is derived from ``${{ github.repository }}``. + ``%%gh_pages%%`` + Replaced by the URL to the associated GitHub Pages webspace. |br| + The value is formatted as ``https://${{ github.repository_owner }}.github.io/${repo}``. + ``%%gh_runid%%`` + Replaced by the pipelines ID. |br| + The value is derived from ``${{ github.run_id }}`` + ``%%gh_actor%%`` + Replaced by the actor (user or bot), who launched the pipeline. |br| + The value is derived from ``${{ github.actor }}``. + ``%%gh_sha%%`` + Replaced by the associated commit's SHA. |br| + The value is derived from ``${{ github.sha }}`` + ``%%date%%`` + Replaced by the current date. |br| + The value is formatted as ``$(date '+%Y-%m-%d')``. + ``%%time%%`` + Replaced by the current date. |br| + The value is formatted as ``$(date '+%H:%M:%S %Z')``. + ``%%datetime%%`` + Replaced by the current date. |br| + The value is formatted as ``$(date '+%Y-%m-%d %H:%M:%S %Z')``. + + +Examples +======== + +.. todo:: + + * GHDL - uses description_file and description + * pyTooling - uses pullrequest + + +.. _JOBTMPL/PublishReleaseNotes/Assets: + +Assets +****** + +.. todo:: + + PublishReleaseNotes::Assets Describe artifact to asset transformation + + Format: ``artifact:file:title`` + + See also: :ref:`JOBTMPL/PublishReleaseNotes/Input/replacements` + + +.. _JOBTMPL/PublishReleaseNotes/Inventory: + +Inventory +********* + +.. todo:: + + PublishReleaseNotes::Inventory Describe how inventory files are created. + + .. _JOBTMPL/PublishReleaseNotes/Parameters: Parameter Summary @@ -125,10 +281,11 @@ ubuntu_image ============ :Type: string -:Required: no +:Required: usually no :Default Value: ``'ubuntu-24.04'`` -:Possible Values: tbd -:Description: tbd +:Possible Values: See `actions/runner-images - Available Images `__ + for available Ubuntu image versions. +:Description: Name of the Ubuntu image used to run a job. .. _JOBTMPL/PublishReleaseNotes/Input/release_branch: @@ -139,8 +296,8 @@ release_branch :Type: string :Required: no :Default Value: ``'main'`` -:Possible Values: tbd -:Description: tbd +:Possible Values: Any valid Git branch name. +:Description: Name of the branch containing releases. .. _JOBTMPL/PublishReleaseNotes/Input/mode: @@ -152,7 +309,7 @@ mode :Required: no :Default Value: ``'release'`` :Possible Values: ``'release'``, ``'nightly'`` -:Description: tbd +:Description: The release mode, which is either *nightly* (a.k.a *rolling* release) or *release*. .. _JOBTMPL/PublishReleaseNotes/Input/tag: @@ -163,8 +320,9 @@ tag :Type: string :Required: yes :Default Value: — — — — -:Possible Values: tbd -:Description: tbd +:Possible Values: Any valid Git tag name. +:Description: Name of the release (tag). +:Condition: It must match an existing tag name in the repository. .. _JOBTMPL/PublishReleaseNotes/Input/title: @@ -175,8 +333,9 @@ title :Type: string :Required: no :Default Value: ``''`` -:Possible Values: tbd -:Description: tbd +:Possible Values: Any valid string suitable for a release title (headline). +:Description: If this parameter is not empty, the releases title is set, which overrides the default title infered + from the associated tag name. .. _JOBTMPL/PublishReleaseNotes/Input/description: @@ -187,8 +346,9 @@ description :Type: string :Required: no :Default Value: ``''`` -:Possible Values: tbd -:Description: tbd +:Possible Values: Any valid (multi-line) Markdown string. +:Description: The description of the release usually used to render the *release notes*. |br| + See :ref:`JOBTMPL/PublishReleaseNotes/ReleaseNotes` for more details. .. _JOBTMPL/PublishReleaseNotes/Input/description_file: @@ -199,8 +359,10 @@ description_file :Type: string :Required: no :Default Value: ``''`` -:Possible Values: tbd -:Description: tbd +:Possible Values: Any valid Markdown file. |br| + Suggested value: :file:`.github/ReleaseDescription.md`. +:Description: Path to a Markdown file used for the release description. |br| + See :ref:`JOBTMPL/PublishReleaseNotes/ReleaseNotes` for more details. .. _JOBTMPL/PublishReleaseNotes/Input/description_footer: @@ -218,8 +380,9 @@ description_footer Published from [%%gh_workflow_name%%](%%gh_server%%/%%gh_owner_repo%%/actions/runs/%%gh_runid%%) workflow triggered by %%gh_actor%% on %%datetime%%. This automatic release was created by [pyTooling/Actions](http://github.com/pyTooling/Actions)::Release.yml -:Possible Values: Any valid text including multi-line text. -:Description: tbd +:Possible Values: Any valid (multi-line) Markdown text. +:Description: A footer added to the description. |br| + See :ref:`JOBTMPL/PublishReleaseNotes/ReleaseNotes` for more details. .. _JOBTMPL/PublishReleaseNotes/Input/draft: @@ -231,7 +394,11 @@ draft :Required: no :Default Value: ``false`` :Possible Values: ``false``, ``true`` -:Description: tbd +:Description: If *true*, the release is kept in *draft* state. + + .. note:: + + GitHub doesn't send e-mail notifications to subscribed users for draft releases. .. _JOBTMPL/PublishReleaseNotes/Input/prerelease: @@ -243,7 +410,7 @@ prerelease :Required: no :Default Value: ``false`` :Possible Values: ``false``, ``true`` -:Description: tbd +:Description: If *true*, the release is marked as a *pre-release*. .. _JOBTMPL/PublishReleaseNotes/Input/latest: @@ -255,7 +422,7 @@ latest :Required: no :Default Value: ``false`` :Possible Values: ``false``, ``true`` -:Description: tbd +:Description: If *true*, the release is marked as *latest release*. .. _JOBTMPL/PublishReleaseNotes/Input/replacements: @@ -266,8 +433,31 @@ replacements :Type: string :Required: no :Default Value: ``''`` -:Possible Values: tbd -:Description: tbd +:Possible Values: Any valid multi-line string of format ``search=replace`` patterns. +:Description: The given replacements are used to replace placeholders in :ref:`JOBTMPL/PublishReleaseNotes/Input/description`, + :ref:`JOBTMPL/PublishReleaseNotes/Input/description_file`, :ref:`JOBTMPL/PublishReleaseNotes/Input/description_footer`. |br| + See :ref:`JOBTMPL/PublishReleaseNotes/ReleaseNotes` for more details. +:Example: The following example replaces the placeholder ``%version%`` with the actual version number (infered + from tag name by :ref:`JOBTMPL/PrepareJob`. + + .. code-block:: yaml + + ReleasePage: + uses: pyTooling/Actions/.github/workflows/PublishReleaseNotes.yml@r5 + needs: + - Prepare + if: needs.Prepare.outputs.is_release_tag == 'true' + permissions: + contents: write + actions: write + with: + tag: ${{ needs.Prepare.outputs.version }} + description: | + # myPackage %version% + + This is the latest release of myPackage. + replacements: | + version=${{ needs.Prepare.outputs.version }} .. _JOBTMPL/PublishReleaseNotes/Input/assets: @@ -278,8 +468,13 @@ assets :Type: string :Required: no :Default Value: ``''`` -:Possible Values: tbd -:Description: tbd +:Possible Values: Any valid multi-line string containing artifact to asset transformations. |br| + The ``artifact:file:title`` format is explained at :ref:`JOBTMPL/PublishReleaseNotes/Assets` +:Description: Each line describes which artifacts to download and extract as well as which extracted file to upload + as a release asset. The files title can be changed. |br| + Replacement rules from parameter :ref:`JOBTMPL/PublishReleaseNotes/Input/replacements` can be used, + too. |br| + See :ref:`JOBTMPL/PublishReleaseNotes/Assets` for more details. .. _JOBTMPL/PublishReleaseNotes/Input/inventory-json: @@ -290,8 +485,11 @@ inventory-json :Type: string :Required: no :Default Value: ``''`` -:Possible Values: tbd -:Description: tbd +:Possible Values: Any valid JSON filename. |br| + Suggested value: :file:`inventory.json`. +:Description: If this parameter is not empty, an inventory of all assets will be created and attached as a JSON file + to the release. |br| + See :ref:`JOBTMPL/PublishReleaseNotes/Inventory` for more details. .. _JOBTMPL/PublishReleaseNotes/Input/inventory-version: @@ -302,8 +500,15 @@ inventory-version :Type: string :Required: no :Default Value: ``''`` -:Possible Values: tbd -:Description: tbd +:Possible Values: Any valid version string. +:Description: If this parameter is not empty, the version field in the inventory JSON is set to this value. |br| + See :ref:`JOBTMPL/PublishReleaseNotes/Inventory` for more details. + + .. hint:: + + Especially for *nightly*/*rolling* releases, the used Git tag is a name rather then a version + number. Therefore, a version number must be provided thus a nightly release can be identified as + ``vX.Y.Z``. .. _JOBTMPL/PublishReleaseNotes/Input/inventory-categories: @@ -314,8 +519,10 @@ inventory-categories :Type: string :Required: no :Default Value: ``''`` -:Possible Values: tbd -:Description: tbd +:Possible Values: A colon separated list of identifiers used as category names in an inventory JSON. +:Description: For decoding hierarchy levels (categories) in an inventory JSON, the hierarchy of categories can be + added to the inventoy JSON. |br| + See :ref:`JOBTMPL/PublishReleaseNotes/Inventory` for more details. .. _JOBTMPL/PublishReleaseNotes/Input/tarball-name: @@ -326,8 +533,9 @@ tarball-name :Type: string :Required: no :Default Value: ``'__pyTooling_upload_artifact__.tar'`` -:Possible Values: tbd -:Description: tbd +:Possible Values: Any valid name for a tarball file. +:Description: + .. todo:: PublishReleaseNotes::tarball-name Needs documentation. .. _JOBTMPL/PublishReleaseNotes/Input/can-fail: @@ -339,7 +547,8 @@ can-fail :Required: no :Default Value: ``false`` :Possible Values: ``false``, ``true`` -:Description: tbd +:Description: + .. todo:: PublishReleaseNotes::can-fail Needs documentation. .. _JOBTMPL/PublishReleaseNotes/Secrets: