Getting base branch SHA on pull request in Github Action Workflow - github

In GitHub action on pull request, I need to run some code in the context of the "current master", and later re-run the same code in the context of the PR branch.
I can check out compare a pull request to the base it is being PR-ed against. How would I find the SHA of the base branch (e.g. current master if PR is against the master)?
jobs:
job_on_base:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
with:
ref: "${{ github.base_ref }}"
- run: |
# Seems like I can get it here with $(git log -1 --format="%H")
echo "My current SHA is ... ?"
job_on_pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
with:
ref: "${{ github.ref }}"
- run: |
echo "My current SHA is $GITHUB_SHA"
echo "The BASE SHA is ?"

If the job runs on a pull_request event the base sha is available as ${{ github.event.pull_request.base.sha }}

This turned out to be a git question, rather than Github actions. The actions/checkout#v2 creates a shallow --depth=1 clone, so to get PR's parent one can parse git cat-file -p output as described here. The first (base) parent could be accessed with
git cat-file -p <SHA> | awk 'NR > 1 {if(/^parent/){print $2; exit}}'
The better approach turned out to be using fetch-depth: 2 parameter. It allows just one job to handle both pull request and master merge cases, and can also be used with HEAD^1 to get to the parent.
steps:
- uses: actions/checkout#v2
with:
fetch-depth: 2

What worked for me was: github.event.workflow_run.head_sha.
The top-voted answer suggesting github.event.pull_request.head.sha didn't work for me.
I found this by examining all the possible data in the github.context object using the method suggested here - https://stackoverflow.com/a/70107953

Related

Unable to Manually Trigger GitHub Action

I recently started working on using some GitHub actions on my projects. I am able to setup them up to run automatically but am struggling with having them run manually. I know that you need the have the workflow_dispatch in the on section. I'm not sure if it's not working because I have it automatically run too. Is someone able to tell me what I am doing wrong?
Here is one of my workflow YAML files
name: Create-Doc-Nightly
on:
push:
branches: [ "nightly" ]
paths:
- 'src/**'
- 'pom.xml'
workflow_dispatch:
jobs:
doc:
name: Create Doc
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
name: Step 1 - Checkout Nightly Branch
with:
persist-credentials: false
fetch-depth: 0
- name: Step 2 - Setup JDK 17
uses: actions/setup-java#v3.4.1
with:
java-version: 17
distribution: 'temurin'
- name: Step 3 - Remove Doc
run: |
git remote set-url origin https://jnstockley:${{ secrets.TOKEN }}#github.com/jnstockley/BTTN.git
git config user.email "jack#jstockley.com"
git config --local user.name "Jack Stockley"
git rm -r docs
git commit -m "Removed Docs"
git push origin nightly
- name: Step 4 - Create Doc
run: mvn dokka:dokka -f pom.xml
- name: Step 5 - Move Docs
run: |
rm -rf docs
mkdir -p docs
mv target/dokka/* docs
- name: Step 6 - Publish docs
run: |
git remote set-url origin https://jnstockley:${{ secrets.TOKEN }}#github.com/jnstockley/BTTN.git
git config user.email "jack#jstockley.com"
git config --local user.name "Jack Stockley"
git add -f docs
git commit -m "Updated Docs"
git push origin nightly
Link to GitHub repo, nightly branch: https://github.com/jnstockley/BTTN/tree/nightly
The workflow must be on your default branch in order to use workflow_dispatch.
I believe in your case it's only on the branch nightly while it should also be on main.
To manually trigger a workflow, use the workflow_dispatch event. You can manually trigger a workflow run using the GitHub API, GitHub CLI, or GitHub browser interface. For more information, see Manually running a workflow
on: workflow_dispatch
Providing inputs
You can configure custom-defined input properties, default input values, and required inputs for the event directly in your workflow. When you trigger the event, you can provide the ref and any inputs. When the workflow runs, you can access the input values in the inputs context. For more information, see Contexts
This example defines inputs called logLevel, tags, and environment. You pass values for these inputs to the workflow when you run it. This workflow then prints the values to the log, using the inputs.logLevel, inputs.tags, and inputs.environment context properties.
yaml
on:
workflow_dispatch:
inputs:
logLevel:
description: 'Log level'
required: true
default: 'warning'
type: choice
options:
- info
- warning
- debug
tags:
description: 'Test scenario tags'
required: false
type: boolean
environment:
description: 'Environment to run tests against'
type: environment
required: true
jobs:
log-the-inputs:
runs-on: ubuntu-latest
steps:
- run: |
echo "Log level: $LEVEL"
echo "Tags: $TAGS"
echo "Environment: $ENVIRONMENT"
env:
LEVEL: ${{ inputs.logLevel }}
TAGS: ${{ inputs.tags }}
ENVIRONMENT: ${{ inputs.environment }}
If you run this workflow from a browser you must enter values for the required inputs manually before the workflow will run.
You might like the following documentation links
workflow_dispatch
github docs - events-that-trigger-workflows

How do I trigger a push to a remote server from a GitHub action?

I have this remote set up from my local
$ git remote -v
dev myuser#mydomain.remote:/home/myuser/maps.git (fetch)
dev myuser#mydomain.remote:/home/myuser/maps.git (push)
In my remote repo, I have a hook, ~/maps.git/hooks/post-receive, with
# The production directory
TARGET="/var/www/html"
# A temporary directory for deployment
TEMP="/home/myuser/deploy-folder"
# The Git repo
REPO="/home/myuser/maps.git"
# Deploy the content to the temporary directory
mkdir -p $TEMP
#git --work-tree=$TEMP --git-dir=$REPO checkout -f
cd $TEMP
git pull
...
What I would like to do is whenever a PR merges into a particular branch (authentication), I would like to trigger a "git push dev" code push to the remote server from a GitHub action. Not quite sure how to fill in my GitHub action. I have this
name: "Build Dev & Release"
on:
push:
paths:
- "**"
- ".github/workflows/my-github-action.yml"
branches:
- authentication
jobs:
pusht-to-dev-server:
???
but not quite sure how to implement the "push-to-dev-server" action.
Edit: In response to the answer given, I created this file
$ cat .github/workflows/directory-dev.yml
name: "Chicommons Maps Dev: Build & Release"
on:
push:
paths:
- "**"
- ".github/workflows/directory-dev.yml"
branches:
- authentication
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
with:
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token.
fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.
- name: Push changes
uses: ad-m/github-push-action#master
with:
github_url: dev.myremote.com:/home/myusername/maps.git
github_token: ${{ secrets.DEPLOY }}
branch: ${{ github.ref }}
and I created this environment encrypted secret
but when I push to my branch (autnentication), I get this error
Run ad-m/github-push-action#master
Push to branch refs/heads/authentication
Missing input "github_token: ${{ secrets.GITHUB_TOKEN }}".
Note that this would assume mydomain.remote is internet-facing (as opposed to on-premise only, behind a DMZ).
That means GitHub servers (where the GitHub action/workflow is executed) must be able to see and contact mydomain.remote.
You can the use the github-push-action, initially made to push to a GitHub repository, but that you can change to include your own domain server.
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
with:
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token.
fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.
- name: Push changes
uses: ad-m/github-push-action#master
with:
github_url: mydomain.remote
github_token: ${{ secrets.YOURDOMAIN_TOKEN }}
branch: ${{ github.ref }}

git actions and LFS cache

trying to mitigate large LFS pulls from github. incurring cost.
so was happy to see caching of large blob coming from LFS is supported in github actions.
here is sample posted on issue #165 at the actions/checkout module repo
- name: Checkout code
uses: actions/checkout#v2
- name: Create LFS file list
run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id
- name: Restore LFS cache
uses: actions/cache#v2
id: lfs-cache
with:
path: .git/lfs
key: ${{ runner.os }}-lfs-${{ hashFiles('.lfs-assets-id') }}-v1
- name: Git LFS Pull
run: git lfs pull
- name: run compile and package
run: python CompileAndPackage.py
my current flow is the following, i declare support for lfs and set submodules support to recursive. the git LFS i call is inside a submodule.
how should i integrate the above into my flow, below.
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
with:
lfs: 'true'
# recursively checkout submodules.
submodules: recursive
i'm not certain the checkout and submodule update (where the lfs pulling i assume occurs) will happen before i check the cache.
here is what i think of using
steps:
- uses: actions/checkout#v2
with:
lfs: 'true'
submodules: recursive
ssh-key: ${{ secrets.git_key }}
- name: Create LFS file list
run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id
- name: Restore LFS cache
uses: actions/cache#v2
id: lfs-cache
with:
path: .git/lfs
key: ${{ runner.os }}-lfs-${{ hashFiles('.lfs-assets-id') }}-v1
- name: Git LFS Pull
run: git lfs pull
should i be explicit about calling git submodule update --init AFTER i check the cache? afaik it happens automagicly by actions/checkout
UPDATE
hey, that looks like it actually worked!
unfrountly github doesnt go into details regarding who took a bite of the LFS quota. would be glad to hear someone says it is legit.
I created an action for this, action-cached-lfs-checkout.
Instead of
- name: Checkout code
uses: actions/checkout#v2
with:
lfs: true
simply do
- name: Checkout code
uses: nschloe/action-cached-lfs-checkout#v1
this is sorted, see update. im closing

Trigger A GitHub Workflow When A New, Separate Repository is Created

I have the following code written which is meant to add a new tag to a repository. This works well if included in the project I'm trying to update directly.
name: Check Github Tags
on: push
jobs:
check-git-tags:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout#v2
with:
fetch-depth: 0
- name: Print Repository info
run: |
echo 'Commit:' $GITHUB_SHA
echo 'Repository:' $GITHUB_REPOSITORY
echo 'Workspace:' $GITHUB_WORKSPACE
echo 'Ref:' $GITHUB_REF
git tag
- name: Push new tag
id: push_new_tag
uses: anothrNick/github-tag-action#1.17.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CUSTOM_TAG: test2
- name: Print New Tag Added
run: echo 'New tag' ${{steps.push_new_tag.outputs.new_tag}} 'added to commit' $GITHUB_SHA 'in' $GITHUB_REPOSITORY.
My question: Can I execute this script from outside of another project / repository? I need to "listen" for any new repositories being created within the organization and then tag the repository to ensure it has the 'test2' tag. So I really only need the workflow to run on the very first push to any new repo. But I don't know who will create the repo, what it will be called, etc. Is it possible to run this as a separate script?

Ways to get last commit author in Github Actions workflow

I am working on converting a Jenkins Pipeline into a Github Actions workflow and need a way of storing the commit author as an environment variable for later use in node.js code.
I have read the documentation and this seems to be the only way I can get it working:
name: Feature Branch PR
on:
pull_request:
types: [opened, edited, synchronize]
push:
branches:
- '**'
Then in the Env section:
env:
AUTHOR: ${{ github.event.pusher.name }}
The problem is this only works for Push triggers. So if i remove the on: push section from top of yml workflow (so it only triggers on PRs) the AUTHOR info becomes empty.
I cannot find a way to get it for commits. Does anyone know of of a way? We do not want this workflow to trigger on pushes.
I also tried
AUTHOR: $(jq '.commits.committer.name' $GITHUB_EVENT_PATH)
I think this was syntactically incorrect though.
For anyone who struggles with this in future, I managed to work it out.
In the node code (not yml) you can obtain an Actions event.json file with all info available. To get the author of a previous commit:
const ev = JSON.parse(fs.readFileSync(process.env.GITHUB_EVENT_PATH, 'utf8'));
return ev.pull_request.user.login;
As YakovL mentioned,
env:
${{ github.event.pull_request.user.login }}
Works fine in a Github action.
To answer the question that was originally asked, you can do the following to get the author of the last commit in a GitHub action:
github.event.commits[0].author.name
For example (to prevent a loop in an action using a personal access token):
name: Version and Package Repo
on:
push:
branches: [ master, main ]
jobs:
build:
if: github.event.commits[0].author.name != 'GitHubActions'
runs-on: ubuntu-18.04
steps:
- name: Checkout repo
uses: actions/checkout#v2
with:
fetch-depth: 0
token: ${{ secrets.PAT }}
- name: Configure git
run: |
git config user.name "GitHubActions"
git config user.email "<>"
- name: Version and Package
run: npm version patch --force
env:
NODE_AUTH_TOKEN: $\{{ secrets.PAT }}
- name: Update git
run: |
git push
git push --tags
You can use this in the interpolation format too:
${github.event.commits[0].author.name}
And if you need to use different github context variables, they are documented at:
https://docs.github.com/en/actions/learn-github-actions/environment-variables
https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#push
Annoyingly, the user details are in different formats for different event types, but in addition to example above (for push), you could try github.event.head.user.login or github.event.base.user.login too