Giter Site home page Giter Site logo

validusa / ghra Goto Github PK

View Code? Open in Web Editor NEW

This project forked from ghalactic/github-release-from-tag

0.0 0.0 0.0 1009 KB

A GitHub Action that creates GitHub Releases from your Git tags. Does what you probably wish GitHub would just do without the need to use GitHub Actions.

Home Page: https://github.com/marketplace/actions/github-release-from-tag

License: MIT License

JavaScript 99.76% Makefile 0.16% Dockerfile 0.08%

ghra's Introduction

GitHub Release from Tag

A GitHub Action that creates GitHub Releases from your Git tags. Does what you probably wish GitHub would just do without the need to use GitHub Actions.

Example release summary

Overview

This action creates releases by sourcing the release data from the place where it makes the most sense to keep it โ€” your Git tags. By harnessing SemVer to determine pre-release status, and Markdown for formatting, your GitHub Releases become a natural extension of your Git tags.

In addition, this action has been designed to feel like it could be a first-party GitHub feature. Its feature set closely mirrors what you have access to when you publish a GitHub Release manually.

Features

Usage

Workflow for tag creation

Most of the time you will want tag pushes to trigger release publishing:

# .github/workflows/publish-release.yml
name: Publish release
on:
  push:
    tags:
      - "*"
jobs:
  publish:
    runs-on: ubuntu-latest
    name: Publish release
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Publish release
        uses: eloquent/github-release-action@v3

It's also possible to use if conditionals to restrict the release publishing step inside a multi-purpose workflow, so that it only runs on tag pushes:

- name: Publish release
  uses: eloquent/github-release-action@v3
  if: github.ref_type == 'tag'

Workflow for manual runs

You may also want to be able to manually publish releases for a specific tag. This allows you to remedy failed publish attempts, or publish tags that were created before automated release publishing was set up:

# .github/workflows/publish-release-manual.yml
name: Publish release (manual)
on:
  workflow_dispatch:
    inputs:
      tag:
        description: The tag to publish
        required: true
jobs:
  publish:
    runs-on: ubuntu-latest
    name: Publish release
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          ref: refs/tags/${{ github.event.inputs.tag }}
      - name: Publish release
        uses: eloquent/github-release-action@v3

GitHub token

Generally speaking, you do not need to supply this action with a custom GitHub token unless you run into some kind of permissions issue, which should not happen under normal operation.

By default, this action uses automatic token authentication to obtain the token used to manage releases. If for some reason you want to supply a different token, you can do so via action inputs:

# In your workflow:
- uses: eloquent/github-release-action@v3
  with:
    token: ${{ secrets.CUSTOM_GITHUB_TOKEN }}

Release stability

This action uses SemVer rules to determine whether a tag should be published as a pre-release, or a stable release. The decision is made as follows:

  • If the tag name is a "stable" SemVer version, it's considered a stable release.
  • If the tag name is an "unstable" SemVer version, it's considered a pre-release.
  • If the tag name is not a valid SemVer version, it's considered a pre-release.

The standard SemVer rules are relaxed a bit to allow for tag names with a v prefix (e.g. v1.2.3), as well as major/minor version tag names (e.g. v1, v1.2) as per GitHub's recommendations for action versioning.

It's also possible to configure an override for this behavior, and force a release to be published as either a pre-release or stable release. This can be done via the configuration file, or via action inputs:

# In .github/release.eloquent.yml:
prerelease: true # or false
# In your workflow:
- uses: eloquent/github-release-action@v3
  with:
    prerelease: "true" # or "false"

Example release stabilities

Tag name Is SemVer? Release stability
1 / v1 no stable release
1.2 / v1.2 no stable release
1.2.3 / v1.2.3 yes stable release
1.2.3+21AF26D3 / v1.2.3+21AF26D3 yes stable release
0.1.0 / v0.1.0 yes pre-release
1.2.3-alpha / v1.2.3-alpha yes pre-release
0 / v0 no pre-release
0.1 / v0.1 no pre-release
something-else no pre-release

Draft releases

This action can be configured to create draft releases. These draft releases can then be published manually at some later time via GitHub. You can enable this feature via the configuration file, or via action inputs:

# In .github/release.eloquent.yml:
draft: true
# In your workflow:
- uses: eloquent/github-release-action@v3
  with:
    draft: "true"

Release name and body

This action generates a release name and body from your tag annotation message. Git already breaks your tag annotation messages into two parts that line up with each part of a GitHub release:

  • The tag annotation subject becomes the release name.
  • The tag annotation body is rendered as Markdown, and used as the release body.

The tag annotation "subject" is just the first paragraph of the message. The "body" is everything that follows:

This is part of the subject.
This is also considered part of the subject.

This is the beginning of the body.
This is also part of the body.

The body can have multiple paragraphs.

Markdown support

For the most part, Markdown "just works" how you would expect. You can write Markdown in the "body" portion of your tag annotations, and it will be rendered in the body of the releases published by this action.

Markdown headings in tag annotation messages

When authoring tag annotation messages, you might run into the issue that Markdown headings are lines that start with a # character, which Git interprets as a comment. You can get around this limitation by using the following Git command to create the tag:

git tag --annotate --cleanup=whitespace --edit --message "" 1.0.0

You might want to add a Git alias to make it easier to remember the command:

git config --global alias.tag-md 'tag --annotate --cleanup=whitespace --edit --message ""'

With the above alias configured, you can then use git tag-md to create tags with Markdown tag annotation bodies:

git tag-md 1.0.0
Markdown line breaks

It's common for tag annotation messages to be "wrapped" at a fixed column width, for readability when viewed as plain text:

1.0.0

This provides an example of a Git tag annotation body that has been
"hard wrapped". This is a very common practice.

If we were to copy the body from the tag annotation message above directly into the GitHub release, the line breaks would be interpreted as explicit line breaks in the final HTML, like so:

This provides an example of a Git tag annotation body that has been
"hard wrapped". This is a very common practice.

Most people would probably consider this an undesirable result, and would rather that the above two lines be combined into a single line in the resulting HTML, similar to how GitHub behaves when rendering README.md files.

To avoid this issue, line breaks that are not followed by another line break (also known as "soft" line breaks) are transformed into spaces before they are used in GitHub release bodies. Meaning the above tag annotation body would be rendered like so:

This provides an example of a Git tag annotation body that has been "hard wrapped". This is a very common practice.

Automated release notes

This action supports GitHub's automatically generated release notes feature. You can enable this feature via the configuration file, or via action inputs:

# In .github/release.eloquent.yml:
generateReleaseNotes: true
# In your workflow:
- uses: eloquent/github-release-action@v3
  with:
    generateReleaseNotes: "true"

When enabled, automated release notes will be generated and appended to each release body. The release notes are based off of pull requests, and can be configured to customize how they are generated.

Example automated release notes

What's Changed

New Contributors

Full Changelog: https://github.com/owner/repo/commits/1.0.0

Release assets

This action supports uploading release assets โ€” files that are associated with a release, and made available for download from GitHub. Release assets must exist before this action is run, and can be specified via the configuration file, or via action inputs:

# In .github/release.eloquent.yml:
assets:
  - path: path/to/asset-a
  - path: path/to/asset-b-*
# In your workflow:
- uses: eloquent/github-release-action@v3
  with:
    # Note the "|" character - this example uses a YAML multiline string.
    assets: |
      - path: path/to/asset-d

โš ๏ธ Warning: This action will overwrite existing release assets if their names match the assets configured for upload. Assets other than the ones specified in configuration or action inputs will not be modified or removed.

Note: Unlike other action inputs, which typically override their equivalent configuration file options, assets specified via action inputs are merged with those specified in the configuration file.

Each asset must have a path property, which is a file glob pattern supported by @actions/glob. If no matching file is found when the action is run, the workflow step will fail (unless the asset is configured to be optional).

If multiple files match the path glob pattern, each file will be uploaded individually. This action does not handle archiving multiple assets for you. If you want to upload a .zip (or similar) file composed of multiple files, you must build the archive yourself prior to running this action.

If a single file matches the path glob pattern, you can additionally specify a custom name and/or label for the asset:

# In .github/release.eloquent.yml:
assets:
  - path: path/to/asset-a.yaml
    name: custom-name.yml
    label: Labels can have spaces
# In your workflow (using YAML):
- uses: eloquent/github-release-action@v3
  with:
    # Note the "|" character - this example uses a YAML multiline string.
    assets: |
      - path: path/to/asset-a.yaml
        name: custom-name.yml
        label: Labels can have spaces
# In your workflow (using JSON):
- uses: eloquent/github-release-action@v3
  with:
    # Note the "|" character - this example uses a YAML multiline string.
    assets: |
      [{
        "path": "path/to/asset-a.yaml",
        "name: "custom-name.yml",
        "label": "Labels can have spaces"
      }]

The name property overrides the file name that will be used when the file is uploaded (and hence the filename seen by users who download the asset). The label property is a text field that gets used by GitHub when viewing a release's assets.

Optional release assets

Assets can be made "optional" โ€” that is, they will simply be skipped if the path file glob pattern does not match any files. You can enable this behavior by setting the optional property to true:

# In .github/release.eloquent.yml:
assets:
  - path: path/to/assets/*
    optional: true
# In your workflow:
- uses: eloquent/github-release-action@v3
  with:
    # Note the "|" character - this example uses a YAML multiline string.
    assets: |
      - path: path/to/assets/*
        optional: true

Dynamic release assets

If you need to dynamically specify a list of assets to upload, you can use the assets action input with generated JSON (or YAML). How you generate the value for this input is up to you, but any value from a context (e.g. an output from another step) can be used, for example:

# Executing a script that outputs JSON describing the assets to upload.
- id: listAssets
  run: echo "assets=$(bash list-assets.sh)" >> $GITHUB_OUTPUT

- uses: eloquent/github-release-action@v3
  with:
    assets: ${{ steps.listAssets.outputs.assets }}

Release discussions

This action supports creating GitHub Discussions for releases. You can enable this feature via the configuration file, or via action inputs:

# In .github/release.eloquent.yml:
discussion:
  category: Announcements
# In your workflow:
- uses: eloquent/github-release-action@v3
  with:
    discussionCategory: Announcements

When enabled, discussions will automatically be created and linked to each published release. The discussion title and body will match the release name and body. The specified discussion category must already exist in the repo.

Reactions

In order to promote engagement with your releases, this action can create reactions like ๐Ÿ‘, ๐Ÿ˜„, ๐ŸŽ‰, โค๏ธ, ๐Ÿš€, and ๐Ÿ‘€.

A typical user is more likely to add their own reaction if they can simply click on an existing one โ€” rather than be the first one to add a particular reaction, which takes more effort. You can enable this feature via the configuration file, or via action inputs:

# In .github/release.eloquent.yml:
reactions: ["+1", laugh, hooray, heart, rocket, eyes]
# In your workflow:
- uses: eloquent/github-release-action@v3
  with:
    reactions: +1,laugh,hooray,heart,rocket,eyes

If you've enabled release discussion creation, reactions can also be created for release discussions (which support a couple of additional reactions like ๐Ÿ‘Ž and ๐Ÿ˜•):

# In .github/release.eloquent.yml:
discussion:
  category: Announcements
  reactions: ["+1", "-1", laugh, hooray, confused, heart, rocket, eyes]
# In your workflow:
- uses: eloquent/github-release-action@v3
  with:
    discussionCategory: Announcements
    discussionReactions: +1,-1,laugh,hooray,confused,heart,rocket,eyes

Job summaries

When a release is created or updated, a summary containing useful information and links will be displayed on the Actions run summary page:

Example release summary

You can disable this feature via the configuration file, or via action inputs:

# In .github/release.eloquent.yml:
summary:
  enabled: false
# In your workflow:
- uses: eloquent/github-release-action@v3
  with:
    summaryEnabled: "false"

Configuration

Tip: Try to use as little configuration as possible. Everything here is optional, and the less configuration the better.

The configuration file

This action supports an optional YAML configuration file, with options for affecting how releases are published:

Note: These options can also be specified by action inputs. A JSON Schema definition is also available.

# .github/release.eloquent.yml

# Set to true to produce releases in a draft state.
draft: true

# Set to true to append automatically generated release notes to the release
# body.
generateReleaseNotes: true

# Set to true or false to override the automatic tag name based pre-release
# detection.
prerelease: false

# Reactions to create for releases.
reactions: ["+1", laugh, hooray, heart, rocket, eyes]

assets:
  # A path is required for each asset.
  - path: assets/text/file-a.txt

  # The "optional" flag, name, and label are optional.
  - path: assets/json/file-b.json
    optional: true
    name: custom-name-b.json
    label: Label for file-b.json

discussion:
  # The category to use when creating the discussion.
  category: category-a

  # Reactions to create for discussions linked to releases.
  reactions: ["+1", "-1", laugh, hooray, confused, heart, rocket, eyes]

summary:
  # Set to false to disable GitHub Actions job summary creation.
  enabled: false

Action inputs

This action supports optional inputs for affecting how releases are published:

Note: With the exception of assets, these inputs take precedence over any equivalent options specified in the configuration file. The action metadata file contains the actual definitions for these inputs.

- uses: eloquent/github-release-action@v3
  with:
    # Set to "true" to produce releases in a draft state.
    draft: "true"

    # Set to "true" to append automatically generated release notes to the
    # release body.
    generateReleaseNotes: "true"

    # Set to "true" or "false" to override the automatic tag name based
    # pre-release detection.
    prerelease: "false"

    # Reactions to create for releases.
    reactions: +1,laugh,hooray,heart,rocket,eyes

    # Assets to be associated with releases, specified as YAML (or JSON), and
    # merged with assets specified elsewhere. If you need a dynamic list, this
    # input can be useful. See the section titled "Dynamic release assets".
    assets: |
      - path: assets/text/file-a.txt

      - path: assets/json/file-b.json
        optional: true
        name: custom-name-b.json
        label: Label for file-b.json

    # Use a custom GitHub token.
    token: ${{ secrets.CUSTOM_GITHUB_TOKEN }}

    # The category to use when creating the discussion.
    discussionCategory: category-a

    # Reactions to create for discussions linked to releases.
    discussionReactions: +1,-1,laugh,hooray,confused,heart,rocket,eyes

    # Set to "false" to disable GitHub Actions job summary creation.
    summaryEnabled: "false"

Action outputs

This action makes a number of outputs available:

Note: The action metadata file contains the actual definitions for these outputs. The example below should give you some idea what each output looks like. The outputs aren't actually YAML of course, it's just for explanatory purposes.

# The ID of the published release.
releaseId: "68429422"

# The URL of the published release.
releaseUrl: https://github.com/owner/repo/releases/tag/1.0.0

# The asset upload URL for the published release (as an RFC 6570 URI Template).
releaseUploadUrl: https://uploads.github.com/repos/owner/repo/releases/68429422/assets{?name,label}

# Contains "true" if a new release was created.
releaseWasCreated: "true"

# The name of the published release.
releaseName: 1.0.0 Leopard Venom ๐Ÿ†

# The body of the published release.
releaseBody: |
  This is the first _stable_ release ๐ŸŽ‰

  ## What's Changed ...

# The avatar URL of the GitHub user who created the tag.
taggerAvatarUrl: https://avatars.githubusercontent.com/u/100152?u=2d625417e12ad2b9cf55a3897e9a36b1bc145133&v=4

# The username of the GitHub user who created the tag.
taggerLogin: ezzatron

# The name of the tag that caused the release.
tagName: 1.0.0

# Contains "true" for any tag considered "stable".
tagIsStable: "true"

# Contains "true" for SemVer version tags.
tagIsSemVer: "true"

# The "subject" portion of the tag annotation.
tagSubject: |
  1.0.0
  Leopard Venom ๐Ÿ†

# The "body" portion of the tag annotation.
tagBody: |
  This is the first
  _stable_
  release ๐ŸŽ‰

# The "body" portion of the tag annotation, rendered as Markdown. This
# represents the Markdown after it has been "processed", and may differ greatly
# from the original input Markdown.
tagBodyRendered: This is the first _stable_ release ๐ŸŽ‰

# The generated release notes produced by GitHub. See "Automated release notes".
generatedReleaseNotes: "## What's Changed ..."

# The ID of the release discussion.
discussionId: D_kwDOG4Ywls4APsqF

# The unique number of the release discussion.
discussionNumber: "93"

# The URL of the release discussion.
discussionUrl: https://github.com/owner/repo/discussions/93

# A JSON array of objects describing the release assets.
assets: |
  [
    {
      "apiUrl": "https://api.github.com/repos/owner/repo/releases/assets/67328106",
      "downloadUrl": "https://github.com/owner/repo/releases/download/1.0.0/file.txt",
      "id": 67328106,
      "nodeId": "RA_kwDOG4Ywls4EA1hq",
      "name": "file.txt",
      "label": "Label for file.txt",
      "state": "uploaded",
      "contentType": "application/json",
      "size": 16,
      "downloadCount": 0,
      "createdAt": "2022-06-02T09:37:56Z",
      "updatedAt": "2022-06-02T09:37:56Z"
    },
    ...
  ]

Using action outputs

Action outputs can be used to integrate with other steps in a workflow. Simply add an id to the step that uses this action, and reference the output you need as demonstrated below:

- uses: eloquent/github-release-action@v3
  id: publishRelease
- env:
    RELEASE_URL: ${{ steps.publishRelease.outputs.releaseUrl }}
  run: echo Released to $RELEASE_URL

The assets output is a JSON array, and needs to be decoded before its contents can be accessed:

Note: The assets are ordered by their name property.

- uses: eloquent/github-release-action@v3
  id: publishRelease
- env:
    DOWNLOAD_URL: ${{ fromJSON(steps.publishRelease.outputs.assets)[0].downloadUrl }}
  run: echo Download the first asset from $DOWNLOAD_URL

GitHub Enterprise Server support

This action works with GitHub Enterprise Server (GHES). Depending on how your enterprise is configured, you may have to work with an administrator to either:

GitHub Enterprise Server version feature support

Feature support on GitHub Enterprise Server often lags behind other versions of GitHub. This action may not work correctly if you try to use features on an enterprise that does not have support for those features.

Here are some key features that can be used by this action, and which version of GitHub Enterprise Server introduced support:

Feature 3.1 3.2 3.3 3.4 3.5 3.6
Release reactions โŒ โœ… โœ… โœ… โœ… โœ…
Generated release notes โŒ โŒ โŒ โœ… โœ… โœ…
Discussions โŒ โŒ โŒ โŒ โŒ โœ…
Job summaries โŒ โŒ โŒ โŒ โŒ โœ…

FAQ

What format should I use for my release body?

I recommend following Keep a Changelog. When it's time to release, just grab the content from the Unreleased section and paste it into your tag annotation message.

Does this action work with Semantic Release / Release Please?

Technically yes, but it's not recommended. These tools have their own solutions for publishing GitHub releases which are better suited.

ghra's People

Contributors

dependabot[bot] avatar ezzatron avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.