Store command response to a variable in Github action - github-actions

I am trying to store the response of aws-cli command to a variable. I am using this:
- name: Check if certificate exists
id: check_certificate
run: echo "::set-output name=S3_RESPONSE::$(aws s3api head-object --bucket test-bucket-ssl --key fullchain.pem)"
- name: Print vars
run: echo "${{steps.check_certificate.outputs.S3_RESPONSE}}"
I am getting blank output even though the S3 API returns a one-line response. If I use a simple command like "echo" instead of AWS command then it works.

Related

Shell script to get AWS Org Root ID fails when running in Github actions workflow

I have the following step in the GitHub workflow that creates an organization in an AWS account and sets AWS Organization Root ID. The problem is that this step fails in Github workflow with exit code 254, but works if I run it via local command line. It's failing because the AWS CLI is returning an error An error occurred (AWSOrganizationsNotInUseException) when calling the DescribeOrganization operation: Your account is not a member of an organization. which expected and the script is supposed to handle it. I'm redirecting all output to stdout, so I'm really scratching my head here trying to figure out why the script is exiting instead of handling failures.
- name: Setup Organization
id: org
run: |
response=$(aws organizations describe-organization 2>&1)
if [ $? -ne 0 ]; then
if echo ${response} | grep -q "AWSOrganizationsNotInUseException"; then
echo "Creating organization..."
aws organizations create-organization --feature-set "ALL"
fi
fi
echo "::set-output name=ROOT_ID::$(aws organizations list-roots --query 'Roots[0].[Id]' --output text)"
shell: bash
Looks like Github Actions executes bash scripts in fail-fast mode (bash --noprofile --norc -e -o pipefail {0}) by default. I had to turn it off to take full control by passing bash {0} to the shell parameter. The following step works in the workflow now in case anyone is struggling with a similar issue.
- name: Setup Organization
id: org
run: |
response=$(aws organizations describe-organization 2>&1)
if [ $? -ne 0 ]; then
if echo ${response} | grep -q "AWSOrganizationsNotInUseException"; then
echo "Creating organization..."
aws organizations create-organization --feature-set "ALL"
fi
fi
echo "::set-output name=ROOT_ID::$(aws organizations list-roots --query 'Roots[0].[Id]' --output text)"
shell: bash {0}

Invalid value. Matching delimiter not found

In updating GitHub actions to reflect the recent announcement deprecating set-output, I have run into the following error attempting to send multiline output to GITHUB_OUTPUT following the provided documentation
Error: Unable to process file command 'output' successfully.
Error: Invalid value. Matching delimiter not found 'e8e24219e2b73f81'
Below is the example action:
name: Action Test
description: test new action output
runs:
using: "composite"
steps:
- name : write
run : |
delimiter="$(openssl rand -hex 8)"
echo "OUT<<${delimiter}" >> $GITHUB_OUTPUT
cat test.json >> $GITHUB_OUTPUT
echo "${delimiter}" >> $GITHUB_OUTPUT
shell : bash
id: write
- name: Print Output
run: echo ${{ steps.write.outputs.OUT }}
shell: bash
In theory this should generate a random delimiter, put it at the beginning and end of the output, and allow the action to then print the multiline file. In practice, I'm unsure what is happening to the second instance of the delimiter as there is no match.
I have tried various solutions such as those posted in this topic
This turned out not to be the issue at hand for the asker, but would lead to the same error message, so leaving it here:
The JSON file is missing a newline at the end, so the actual contents written to the output file look something like
OUT<<eabbd4511f4f29ab
{"key":"value"}eabbd4511f4f29ab
and the closing delimiter can't be found because it's not at the beginning of a line.
To fix, we can apply this answer to add a newline if it's missing:
run : |
delimiter=$(openssl rand -hex 8)
{
echo "OUT<<$delimiter"
sed -e '$a\' test.json
echo "$delimiter"
} >> "$GITHUB_OUTPUT"
shell: bash

github worflow fails when running a grep command that does not found anything

I'm working on a workflow that has the following step:
- name: Analyze blabla
run: grep -Ri --include \*.ts 'stringToBeSearched' ./tmp/bla > ./tmp/results.txt
shell: bash
This works well in the case the grep command founds something. Then the found lines are dumped into results.txt and the returncode is 1, and the workflow goes to the next step as expected
But in the case the grep command does not found the searched strings, then an empty file is saved as result.txt (what correct until this point), but the result code is 0, and the step is set as failed, and the whole workflow fails.
Is there a way to not set the step as failed when the result code is 0?
Thanks
You could use the continue-on-error step option:
jobs.<job_id>.steps[*].continue-on-error
Prevents a job from failing
when a step fails. Set to true to allow a job to pass when this step
fails
Like:
- name: Analyze blabla
continue-on-error: true
id: grep
run: grep -Ri --include \*.ts 'stringToBeSearched' ./tmp/bla > ./tmp/results.txt
shell: bash
You. could check the outcome of the step in order to understand if was failed or not like:
steps.<id>.outcome != 'success'
See outcome doc here

How to store an AWS CLI query result to a GitHub environment variable to be used in the same workflow?

I'm trying to query AWS to get a certain CloudFront Distribution Id and store it in a GitHub Actions environment variable so I could us it to invalidate that CloudFront Distribution. This is what I've tried so far:
name: Store CloudFront Distribution Id in env variable
env:
DIST_ID: ""
run: |
aws cloudfront list-distributions --query "DistributionList.Items[*].{id:Id,origin:Origins.Items[0].Id}[?origin=='$AWS_S3_BUCKET'].id" --output text > "$DIST_ID"
Any ideas on how I can accomplish this? Thanks
If you want to set an environment variable from a script, it's easiest to append it to the special file behind $GITHUB_ENV as described in the docs:
echo "{environment_variable_name}={value}" >> $GITHUB_ENV
In your case, this would mean:
steps:
- run: |
DIST_ID=$(aws cloudfront list-distributions --query "DistributionList.Items[*].{id:Id,origin:Origins.Items[0].Id}[?origin=='$AWS_S3_BUCKET'].id" --output text)
echo "DIST_ID=$DIST_ID" >> $GITHUB_ENV
- run: echo ${{ env.DIST_ID }}

How to install scoped private npm package from Artifactory in Github Actions

This question includes a specific use-case:
I have a private scoped package: #myscope/mypackage
It hosted in Artifactory NPM registry: https://company.jfrog.io/artifactory/api/npm/my-npm-registry/
I need to use my credentials to consume it.
I want to consume it in Github Actions.
How can I do that?
.npmrc
First, you need to configure your access in a local .npmrc file. You can put this file in your source root folder.
always-auth = true
# First, set a different registry URL for your scope
#myscope:registry=https://company.jfrog.io/artifactory/api/npm/my-npm-registry/
# Then, for this scope, you need to set the token
//company.jfrog.io/artifactory/api/npm/my-npm-registry/:_auth = {{your token - see below}}
Token
You need to get the NPM Token from Artifactory (note it isn't your API Key.
Get your Artifactory API Key from your Artifactory profile: https://company.jfrog.io/ui/admin/artifactory/user_profile
Run the next command on your Linux terminal: curl -u {{ ARTIFACTORY_USERNAME }}:{{ ARTIFACTORY_API_KEY }} https://company.jfrog.io/artifactory/api/npm/auth/
Powershell:
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f {{ ARTIFACTORY_USERNAME }},{{ ARTIFACTORY_API_KEY }})))
Invoke-RestMethod -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} https://company.jfrog.io/artifactory/api/npm/auth/
You should receive this:
_auth = {{ YOUR_NPM_TOKEN }}
always-auth = true
So now you can take this Token and put it in the .npmrc file above.
Github Actions
How to do all this in Github Actions?
First, save your Jfrog username and API Key in Github Secrets: JFROG_USER & JFROG_PAT.
And you can add the next step to your workflow, after checkout and before yarn/npm install:
- name: npm token
run: |
echo "#myscope:registry=https://company.jfrog.io/artifactory/api/npm/my-npm-registry/" > .npmrc
echo "//company.jfrog.io/artifactory/api/npm/my-npm-registry/:$(curl -u ${{ secrets.JFROG_USER }}:${{ secrets.JFROG_PAT }} https://company.jfrog.io/artifactory/api/npm/auth/)" >> .npmrc