0

I'm trying to create a function in a Jenkins shared library that spits out the last commit hash of the parent branch of the current git branch.

ParentBranch = foo

ChildBranch(Forked from parent) = bar

What I want to get is the commit hash for the last commit in foo branch

I've written this script and tested it on my local machine

#! /bin/bash
PARENT_BRANCH=$(git show-branch -a | grep '\*' | grep -v `git rev-parse --abbrev-ref HEAD` | head -n1 | sed 's/.*\[\(.*\)\].*/\1/' | sed 's/[\^~].*//')
PARENT_COMMIT=$(git rev-parse $PARENT_BRANCH | cut -c-20)
printf $PARENT_COMMIT

And this works perfectly.

But when I put it in a function in Jenkins, it doesn't seem to do anything. I've tried to escape the special characters too.

def call() {
sh '''
cat <<EOF > gitBranch.sh
#! /bin/bash
PARENT_BRANCH="$(git show-branch | grep '*' | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -n1 | sed 's/.*\\[\\(.*\\)\\].*/\\1/' | sed 's/[\\^~].*//')"
PARENT_COMMIT="$(git rev-parse ${PARENT_BRANCH} | cut -c-20)"
printf "${PARENT_COMMIT}"
EOF
'''
}

In my Jenkins console output, when I cat the file gitBranch.sh, this is what I get

#! /bin/bash
PARENT_BRANCH=""
PARENT_COMMIT=""
printf ""

Nothing gets expanded.

What am I doing wrong please?

torek
  • 448,244
  • 59
  • 642
  • 775
Hammed
  • 1,457
  • 1
  • 24
  • 37
  • 1
    Looks more like the problem is that *everything* is expanded. I don't know how Jenkins substitutes things, but from the shell point of view you can use `cat << "EOF"` with quoted end token to avoid this. Also note that the script you say you tested on your local machine is a different version from the script you're trying put in `gitBranch.sh`, and computers care a lot about even minor differences. – that other guy Aug 26 '21 at 23:26
  • Never seena space in `#!/bin/bash` before. Add a line `git --version` and see if it's finding **git** inside the `sh`. – Ian W Aug 27 '21 at 01:06
  • @IanW: that space was once *required*. In modern systems, it has become optional. – torek Aug 27 '21 at 08:05
  • Well, I never knew that; guess you're never too old to learn something new. Been using Linux since '96, and used Solaris, HP-UX, AIX, QNX and never came across that ! Seems Q has been asked [before](https://unix.stackexchange.com/questions/276751/is-space-allowed-between-and-bin-bash-in-shebang); interesting [lore](https://web.archive.org/web/20170215070707/http://www.in-ulm.de/~mascheck/various/shebang/#blankrequired) ... " But it turns out that it is virtually impossible to find a Unix which actually required this." – Ian W Aug 27 '21 at 08:34
  • @IanW: Huh. I had thought the requirement was in 4.1BSD (which I used in the early 1980s), but maybe it was just in the *documentation*. – torek Aug 27 '21 at 09:43
  • @torek, I guess, "never believe anything you read on the internet/usenet” and ["don't trust anything on S/O"](https://ieeexplore.ieee.org/document/7958574) ! ;) – Ian W Aug 27 '21 at 10:15

1 Answers1

2

Your problem here is Jenkins (so I removed the non-Jenkins tags): Jenkins uses Groovy for commands, and Groovy does its own $ interpolation in strings. You just need to protect these particular dollar signs. See also Using "$" in Groovy and illegal string body character after dollar sign : either escape a literal dollar sign "\$5" or bracket the value expression.

(I am not a Jenkins or Groovy expert and I have no love at all for Jenkins, but this is something anyone using it should know, because it's pretty evil that way.)

torek
  • 448,244
  • 59
  • 642
  • 775