GitHub custom checks - github

I'd like to integrate custom checks into some repos, but I can't figure out the best way to do this.
We have pretty large team of developers and we've introduced some naming conventions to maintain consistency in our repo. For example, every commit description should contain X, and every branch name should contain Y or Z, or have a match to some regular expression.
How do I enforce some custom checks on pull request, that branch that is being checked complies to these specified rules? Simply put, when pushed commits don't have Jira reference in their description - merge action is blocked. We also want to see these checks in the PR, like those CI checks which can pass or fail.
I've read about github apps, actions, api, marketplace and etc. Couldn't find something simple and straightforward.
What app or approach should I utilize for such a task?

The easiest way to do this is with a GitHub Action, which will allow you to execute whatever code you want to implement CI or linting checks.
You can create a shell script in your repository (for example, script/lint) that takes two arguments, the base branch and the branch being tested. Lint and check whatever you want, printing useful error messages and exiting zero if the commits are acceptable and nonzero if they're unacceptable.
Then create a workflow in .github/workflow/lint.yml with something like this (changing the script name if need be):
name: lint
on: pull_request
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#master
- run: script/lint "$GITHUB_SHA" "$GITHUB_REF"
This will appear in the checks interface like other CI checks under the name “Lint.” You can customize the name field to change the name.
An example lint script that checks for JIRA tags in commit messages might look like this:
#!/bin/sh
RET=0
for i in $(git rev-list "$1".."$2")
do
printf "Checking $i for JIRA reference..."
if git log -1 --format="%B" $i | grep -qsE "[A-Z]+-[0-9]+"
then
echo "looks ok."
else
echo "failed."
RET=1
fi
done
exit $RET

Related

Using `GITHUB_REF` when triggering a reusable workflow

I'm trying to call multiple workflows from a single one and I want to use the commit sha, or the branch name or something to get the workflow file with the recent changes on the branch the workflows are triggered on.
For example, I am on a branch <feature_branch> and I want to trigger the workflow's on that branch. I want the content of the later called workflows also to be the one from that branch. For that reason, I tried the following:
// My repository structure's essential part
repo_folder
> .github
| > workflows
| | > main-ci.yml
| | > other-workflow.yml
# main-ci.yml
name: Main CI workflow
on: ...
jobs:
uses: <my_repo>/.github/workflows/other-workflow.yml#$GITHUB_REF
...
# other-workflow.yml
...
The issue is that when GitHub parses the main-ci workflow it doesn't seem to resolve the $GITHUB_REF environment variable before trying to call the workflow, and reports a problem
error parsing called workflow "<my_repo>/.github/workflows/other_workflow.yml#$GITHUB_REF": failed to fetch workflow: reference to workflow should be either a valid branch, tag, or commit
I tried with context variables too (like ${{ github.sha }}) but with that syntax, it asks for removing the spaces from the version field.
Just figured this out after heading out to the workflow syntax section of the GitHub actions' documentation. It says:
If you use the second syntax option (without {owner}/{repo} and #{ref}) the called workflow is from the same commit as the caller workflow.
And the example shows
jobs:
call-workflow-1-in-local-repo:
uses: octo-org/this-repo/.github/workflows/workflow-1.yml#172239021f7ba04fe7327647b213799853a9eb89
call-workflow-2-in-local-repo:
uses: ./.github/workflows/workflow-2.yml
call-workflow-in-another-repo:
uses: octo-org/another-repo/.github/workflows/workflow.yml#v1
So, all I needed to do is to change
uses: <my_repo>/.github/workflows/other-workflow.yml#$GITHUB_REF
to
uses: ./.github/workflows/other-workflow.yml

Update/Edit of workflow file in GitHub action

I have configured a manual workflow and it runs OK, but once I update/edit it and commit it to the same branch, the changes do not affect it. I mean the action still runs but uses the old version of the workflow file. is there any step I need to do?
Steps I followed for editing the workflow file:
https://docs.github.com/en/actions/learn-github-actions/finding-and-customizing-actions#browsing-marketplace-actions-in-the-workflow-editor
Here is workflow file details, just in case
The original:
# This is a basic workflow to help you get started with Actions
name: CI
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "development" branch
release:
types: [created]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout#v3
# Runs a single command using the runners shell
- name: Run a one-line script
run: echo Hello, world Nikzad!, 3
Note: Let's say I just replace the last line with the bellow line, but my output still says Hello, world Nikzad!, 3 where it should say Hello, world Nikzad!, 4.
run: echo Hello, world Nikzad!, 4
I found my problem. actually, when we are creating a new release, we are providing a tag name for that release, and when we create that tag name and push it to the repo, the version of the workflow at that point is what matters, so when I want to edit or update my workflow, I do the followings:
Edit the workflow (Make any change you want, eg change the title or add echo)
Commit and push workflow changes
Create a new tag and push
From the GitHub panel, create a new release based on the new tag
Now I see the action is running based on the new workflow
Note: Maybe it is more about learning of the process, but I did not find it straight forward anywhere, I hope it helps someone.

How to exclude certain branches for a path pattern within Github Actions?

How to apply branches-ignore and paths-ignore on GitHub Actions? For example, if I have the following source tree:
|-src\
|----reports\
|-------<foo>DailyReports.ts
I want to only deploy that to production (master branch) but NOT staging (staging branch).
Any advice and insight is appreciated.
You won't be able to achieve what you want with ON trigger configuration alone. Therefore the implementation below wouldn't work as it would trigger for push to the specified path OR for push to the master branch, but not only for both:
on:
push:
path:
- 'src/reports/*DailyReports.ts'
branches:
- master
In that case, you could do it by using only one trigger at the workflow level, and check the other condition with an IF expression.
For example by doing this:
on:
push:
path:
- 'src/reports/*DailyReports.ts'
jobs:
job1:
runs-on: ...
if: github.ref == 'refs/heads/master' # run this job only for the master branch
steps:
...
Or by checking the branch at the workflow level, and then use something like this path-filter action to check if the file or directory has been updated or not before performing some operation.
I personally suggest the first option (cf example), as it's less verbose.
Note: If the src/reports/*DailyReports.ts path isn't working as expected, you can use the filter pattern cheat sheet to find the right expression.

Mark a conditional Github Action as required

I have a Github action in my repository that runs only when a specific file has changed. I have marked this action as required in repository settings so that whenever it fails the automatic merge gets blocked. Merge block is working fine but if a PR doesn't include a change to that specific file, Github still blocks the PR waiting for the job to complete which won't even run. Ideally, Github should ignore this action if it is not applicable.
I have put up a public repository that showcases this behavior. There are two PRs open: one that is working fine and the other one is blocked.
Any suggested workaround for this?
A workaround could be to update the workflow to run independently of the path, but check the path in the job execution with something like the path filter action, then return the message you want on the PR if the label isn't set and set an error to block the merge, or return that everything is ok if the file hasn't been updated.
Your workflow would in that case looks like below:
name: All Checked Verifier
on:
pull_request:
types: [labeled, unlabeled, opened, edited, synchronize]
jobs:
enforce-label:
runs-on: ubuntu-latest
steps:
- uses: dorny/paths-filter#v2
id: changes
with:
filters: |
public_api_views:
- '**/code.py'
- if: steps.changes.outputs.public_api_views == 'true'
uses: yogevbd/enforce-label-action#2.1.0
with:
REQUIRED_LABELS_ALL: "checked-everything"
REQUIRED_LABELS_ALL_DESCRIPTION: "Make sure we have checked everything and once done, add label 'checked-everything' to this PR."
It's weird because the https://github.com/sferhan/hello-github-actions/pull/6 not excuting the workflow
and i forked the repo https://github.com/bxb100/hello-github-actions, it's work fine... so i guess the action have problem.

How to version build artifacts using GitHub Actions?

My use case is I want to have a unique version number for artifacts per each build/run. With current tools like CircleCI, Travis, etc. there is a build number available which is basically a counter that always goes up. So, I can create version strings like 0.1.0-27. This counter is increased each time even for the same commit.
How can I do something similar with GitHub Actions? Github actions only offer GITHUB_SHA and GITHUB_REF.
GitHub Actions now has a unique number and ID for a run/build in the github context.
github.run_id : A unique number for each workflow run within a repository. This number does not change if you re-run the workflow run.
github.run_number : A unique number for each run of a particular workflow in a repository. This number begins at 1 for the workflow's first run, and increments with each new run. This number does not change if you re-run the workflow run.
github.run_attempt : A unique number for each attempt of a particular workflow run in a repository. This number begins at 1 for the workflow run's first attempt, and increments with each re-run.
ref: https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context
You can reference them in workflows like this:
- name: Output Run ID
run: echo ${{ github.run_id }}
- name: Output Run Number
run: echo ${{ github.run_number }}
- name: Output Run Attempt
run: echo ${{ github.run_attempt }}
I had the same problem and have just created an action to generate sequential build numbers. Use it like
- uses: einaregilsson/build-number#v1
with:
token: ${{secrets.github_token}}
In steps after that you'll have a BUILD_NUMBER environment variable. See more info about using the same build number for different jobs and more at https://github.com/einaregilsson/build-number/
UPDATE: There is now a $GITHUB_RUN_NUMBER variable built into GitHub Actions, so this approach is not needed anymore.
If you want a constant integer increment (1,2,3,4,5), I haven't found anything in the docs that you could use as such increment which is aware of how many times that particular action ran. There's two solutions I can think of:
Maintaining state on the repo: for example with a count.build file that uses the workflow ID and you increment it on build. This is my least favourite solution of the two because it adds other complexities, like it will itself trigger a push event. You could store this file somewhere else like S3 or in a Gist.
Using the Date: if you're not worried about sequence on the integer increment you could just use the current data and time, for example 0.1.0-201903031310 for Today at 13:10.
Regardless if you have Actions Beta Access, I would definitely feed this back to GitHub.
Hope it helps.
You can use GitVersion to generate incrementing versions from tags in Git. The PR at https://github.com/GitTools/GitVersion/pull/1787 has some details, but basically you can define this job:
- uses: actions/checkout#v1
- name: Get Git Version
uses: docker://gittools/gitversion:5.0.2-beta1-34-linux-debian-9-netcoreapp2.1
with:
args: /github/workspace /nofetch /exec /bin/sh /execargs "-c \"echo $GitVersion_MajorMinorPatch > /github/workspace/version.txt\""