Output of bash command substitution?

Hi,

In our project, we have a Makefile, with a step to build our docker container. The real version is a bit more complex than the example below, but it captures the gist of what we’re doing.

docker-build:
	@echo "🚀 Building docker image"
	@docker build \
		-t ${DOCKER_IMAGE} .
	@echo ${DOCKER_IMAGE}

${DOCKER_IMAGE} is calculated based on commit SHA etc. Part of this is that we want to capture the calculated container name + tag, so we echo ${DOCKER_IMAGE} and capture it in our github action like this

- name: Docker (build)
  id: container
  run: |
    label=$(make docker-build | tail -1)
    echo "::set-output name=label::$label"

- name: Display container SHA
  run: echo ${{ steps.container.outputs.label }}

Which works great. The problem is that since we need to capture output of the make recipe, we need to call it using a bash command substitution $(make docker-build | tail -1) however, when we do this we do not get any output of the docker build command, which would make troubleshooting difficult if we ever run into problems.

The exact same setup works fine locally on our machines, but the stdout from the inner docker build is suppressed by GitHub Actions.

Does anyone have suggestions on how we could continue capturing the output, while also getting the output of the docker build command to be displayed?

Thanks!

How about writing DOCKER_IMAGE to a file from the Makefile, instead of capturing output? Later steps could then read it from that file, and the only “cost” to local builds is one tiny additional output file. :slightly_smiling_face:

To be honest I’d like to avoid creating a bunch of artifacts from my Makefile since we run them locally as well. Like I said, this works flawless locally since it’s not Make that’s hiding the output, it seems to be GitHub Actions

Running label=$(make docker-build | tail -1) locally both gets me the output as well as the build log of my Docker image

Then copy the output to a file in the Actions workflow before processing it, something like this:

make docker-build | tee output.log
label=$(tail -1 output.log)

I decided to go another way. Since the generated container image name (and tag) is idempotent for the same commit, I decided to add a docker-info recipe in my Makefile. I simply call that to get the name

1 Like