Creating signed tags in a Github action.

Hello,

I have a question of how to handle the Github Actions environment.

In one of my repos, I am trying to automate the creation of release tags when merging to master.

My current approach consists of using octokit/rest.js to access Github when an action is triggered: When a pull request to master has been closed and merged, the action executes a Node file which, using a personal Github token, calls git.createTag and git.createRef, which creates the Tags. In a nutshell:

My Github action:

on:
   pull_request:
       ...

jobs:
...
uses: my_actions/generate-tags@v1
with:
token: ${{ secrets.MY_TOKEN }}
otherParams: otherParams

My js file:

...  
const github = require('@actions/github');
...  
const oct =new github.GitHub(MY_TOKEN);
octokit.git.createTag(params).then(// SAVE tag_sha);
octokit.git.createRef(tag_sha);

This works. However, I would like the Tags to be signed (verified) as well. Is it there any  approach where tags (or any action in general) clould be signed within a Github action environment? How can/should I provide a PGP key to octokit/rest.js to sign? Should I use some bash commands instead/before?

Thank you!

1 Like

Hi @jmonguilo , 

I tested this action : mathieudutour/github-tag-action . I can automatically bump and tag master, on merge, with the latest SemVer formatted version.  And the tag created by this action has “Verified” tag.

The workflow is triggered by pull_request not push event. 

There is the ts file of the action: https://github.com/mathieudutour/github-tag-action/blob/master/src/main.ts

If this could not help, could  you share your action here? 

Hi @yanjingzhu, thank you for your reply!.

I am trying to use a personal access token instead of Github’s token. I still need to figure out how to pass signature information as well.

Nevertheless, I have also tried to use GITHUB_TOKEN instead of MY_TOKEN, and could not get the verified tag. Perhaps something different in my approach with respect?

Here is the complete code I am using to test the action (putting manually tag names fot the moment, but the interaction with octokit at the end is the same as mathieudutour/github-tag-action):

./.github/workflows/release.yml

name: Release Pull Request

on:
  pull_request:

jobs:
  signed-commit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v1
      - name: Tags
        uses: ./tag
        with:
          token: ${{ secrets.MY_TOKEN }}
          tag: '2020/04/28'
          message: 'Release test'
          commit: ${{ github.event.pull_request.head.sha }}

./tag/index.js action:

const cp = require('child_process');

cp.execSync(`cd ${__dirname}; yarn install`);

const core = require('@actions/core');
const github = require('@actions/github');

async function tag() {

    const token = core.getInput("token", { required: true });
    const tagName = core.getInput("tag", { required: true });
    const tagMessage = core.getInput("message", { required: true });
    const [repoOwner, repoName] = process.env.GITHUB_REPOSITORY.split("/");

    const oct = new github.GitHub(token);

    const createdTag = await oct.git.createTag({
        owner: repoOwner,
        repo: repoName,
        tag: tagName,
        message: tagMessage,
        object: process.env.GITHUB_SHA,
        type: "commit"
    });

    if (createdTag.status !== 201) {
        core.setFailed(`Could not create tag. Received ${createdTag.status} from API`)
    }

    await oct.git.createRef({
        owner: repoOwner,
        repo: repoName,
        ref: 'refs/tags/' + tagName,
        sha: createdTag.data.sha
    }).then(
        ({ status }) => {
            if (status !== 201) {
                core.setFailed(`Could not create reference. Received ${status} from API`)
            }
        }
    )
}

tag().catch(
    (err) => {
        core.setFailed(err.message)
    }
);

Hi @jmonguilo , 

Thank you for sharing your index.js file . I have tested it in my action. The tag created by this action doesn’t have a verified symbol. I am trying to ask for help from github engineering team. This may take sometime. Appreciate your patience.

@jmonguilo  I got response from engineering team. 

In your action, new tag is created using REST API, there is no method to create a signed tag using REST API.

The action mathieudutour/github-tag-action I provided before , it does the signing of the commit on the command line and then pushes it up. 

We would encourage you to customize github-tag-action instead of using octokit directly.  

nice, now actions can do that now. Sweet.

Hi @yanjingzhu 

Thank you very much, indeed I think I will use this approach in the future.

On the mean time, I have used Octokit’s create release

oct.repos.createRelease

which for this particular case its acceptable and creates a signed tag with the committer signature.