Skip to content

Commit

Permalink
never alone cleanup 1 (#313)
Browse files Browse the repository at this point in the history
* Some cleanup

* Added reason for non compliance
  • Loading branch information
ToreMerkely authored Sep 6, 2024
1 parent 912afdc commit b80b7c2
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 94 deletions.
11 changes: 6 additions & 5 deletions .github/workflows/init_kosli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ jobs:
--org ${{inputs.kosli_org}}


- name: Attest never alone data to Kosli Trail
- name: Report never-alone attestation to Kosli
if: ${{ github.ref == 'refs/heads/main' }}
env:
KOSLI_API_TOKEN: ${{ secrets.kosli_api_token }}
Expand All @@ -88,15 +88,16 @@ jobs:
./bin/never_alone/get_commit_and_pr_info.sh -c ${GITHUB_SHA} -o ${USER_DATA_FILENAME}
PR_URL=$(cat ${USER_DATA_FILENAME} | jq -r '.pullRequest.url // empty')
PR_ANNOTATE_ARG=""
if [ -n "$PR_URL" ]; then
PR_ANNOTATE_ARG="--annotate pull_request=$PR_URL"
else
PR_ANNOTATE_ARG=""
fi
kosli attest generic \
--org ${{inputs.kosli_org}} \
--flow ${{inputs.flow_name}} \
--trail ${{inputs.trail_name}} \
--org=${{inputs.kosli_org}} \
--flow=${{inputs.flow_name}} \
--trail=${{inputs.trail_name}} \
--name=never-alone-data \
--compliant=true \
--user-data="${USER_DATA_FILENAME}" \
Expand Down
7 changes: 3 additions & 4 deletions .github/workflows/never_alone_trail.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ jobs:
- name: setup-kosli-cli
uses: kosli-dev/setup-cli-action@v2
with:
version:
${{ vars.KOSLI_CLI_VERSION }}
version: ${{ vars.KOSLI_CLI_VERSION }}

- name: Update never-alone flow
env:
Expand All @@ -64,12 +63,12 @@ jobs:
KOSLI_ORG: ${{ inputs.kosli_org }}
GH_TOKEN: ${{ github.token }}
run: |
BASE_COMMIT=$(./bin/never_alone/get_commit_of_latest_release.sh)
START_COMMIT_SHA=$(./bin/never_alone/get_commit_of_latest_release.sh)
./bin/never_alone/create_never_alone_trail.sh \
-f ${{inputs.flow_name}} \
-t ${{inputs.trail_name}} \
-b ${BASE_COMMIT} \
-b ${START_COMMIT_SHA} \
-c ${GITHUB_SHA} \
-s ${{inputs.source_flow_name}} \
-n ${{inputs.attestation_name}} \
Expand Down
181 changes: 96 additions & 85 deletions bin/never_alone/create_never_alone_trail.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ set -Eeu
SCRIPT_NAME="create_never_alone_trail.sh"
FLOW_NAME=""
TRAIL_NAME=""
BASE_COMMIT=""
CURRENT_COMMIT=""
SOURCE_FLOW=""
START_COMMIT_SHA=""
END_COMMIT_SHA=""
SOURCE_FLOW_NAME=""
SOURCE_ATTESTATION_NAME=""
PARENT_FLOW=""
PARENT_TRAIL=""
PARENT_FLOW_NAME=""
PARENT_TRAIL_NAME=""
KOSLI_HOST=${KOSLI_HOST:-https://app.kosli.com}


Expand All @@ -19,18 +19,18 @@ function print_help
Use: $SCRIPT_NAME [options]
Script to create a trail for collecting never-alone information from multiple commits.
Collects all commits between base-commit and proposed-commit and use it as a template for the trail.
Collects all commits between start-commit-sha and end-commit-sha and use it as a template for the trail.
Options are:
-h Print this help menu
-f <flow-name> Name of kosli flow to report combined never-alone info to. Required
-t <trail-name> Name of the trail that the reviews shall be reported to. Required
-b <base-commit-sha> Old commit sha, used as base for creating list of commits. Required
-c <commit-sha> Current commit sha, used as the end point for creating list of commits. Required
-s <source-flow> Name of kosli flow where the never-alone-data data are stored. Required
-n <attestation-name> Attestation name used for never-alone-data. Required
-p <parent-flow> Send an attestation about the never-alone-trail to the parent-flow. Optional
-q <parent-trail> Trail name of parent flow where the report shall be sent. Optional
-h Print this help menu
-f <flow-name> Name of kosli flow to report each commits never-alone compliance. Required
-t <trail-name> Name of the trail to report each commits never-alone compliance. Required
-b <start-commit-sha> Start commit sha, used for creating list of commits. Required
-c <end-commit-sha> End commit sha, used for creating list of commits. Required
-s <source-flow-name> Name of kosli flow where never-alone-data for each commit is stored. Required
-n <source-attestation-name> Attestation name used for never-alone-data for each commit. Required
-p <parent-flow-name> Send an attestation about the never-alone-trail to the parent-flow. Optional
-q <parent-trail-name> Trail name of parent flow where the report shall be sent. Optional
EOF
}

Expand Down Expand Up @@ -63,22 +63,22 @@ function check_arguments
TRAIL_NAME=${OPTARG}
;;
b)
BASE_COMMIT=${OPTARG}
START_COMMIT_SHA=${OPTARG}
;;
c)
CURRENT_COMMIT=${OPTARG}
END_COMMIT_SHA=${OPTARG}
;;
s)
SOURCE_FLOW=${OPTARG}
SOURCE_FLOW_NAME=${OPTARG}
;;
n)
SOURCE_ATTESTATION_NAME=${OPTARG}
;;
p)
PARENT_FLOW=${OPTARG}
PARENT_FLOW_NAME=${OPTARG}
;;
q)
PARENT_TRAIL=${OPTARG}
PARENT_TRAIL_NAME=${OPTARG}
;;
\?)
echo "Invalid option: -$OPTARG" >&2
Expand All @@ -93,83 +93,84 @@ function check_arguments
if [ -z "${TRAIL_NAME}" ]; then
die "option -t <trail-name> is required"
fi
if [ -z "${BASE_COMMIT}" ]; then
die "option -b <base-commit-sha> is required"
if [ -z "${START_COMMIT_SHA}" ]; then
die "option -b <start-commit-sha> is required"
fi
if [ -z "${CURRENT_COMMIT}" ]; then
die "option -c <commit-sha> is required"
if [ -z "${END_COMMIT_SHA}" ]; then
die "option -c <end-commit-sha> is required"
fi
if [ -z "${SOURCE_FLOW}" ]; then
die "option -s <source-flow> is required"
if [ -z "${SOURCE_FLOW_NAME}" ]; then
die "option -s <source-flow-name> is required"
fi
if [ -z "${SOURCE_ATTESTATION_NAME}" ]; then
die "option -n <attestation-name> is required"
die "option -n <source-attestation-name> is required"
fi
if { [[ -n "$PARENT_FLOW" && -z "$PARENT_TRAIL" ]] || [[ -z "$PARENT_FLOW" && -n "$PARENT_TRAIL" ]]; }; then
die "You must provide either both options -p <parent-flow> and -q <parent-trail>, or neither"
if { [[ -n "$PARENT_FLOW_NAME" && -z "$PARENT_TRAIL_NAME" ]] || [[ -z "$PARENT_FLOW_NAME" && -n "$PARENT_TRAIL_NAME" ]]; }; then
die "You must provide either both options -p <parent-flow-name> and -q <parent-trail-name>, or neither"
fi
}

function begin_trail_with_template
{
local flow_name=$1; shift
local trail_name=$1; shift
local commits=("$@")
local trail_template_file_name="review_trail.yaml"
local -r flow_name=$1; shift
local -r trail_name=$1; shift
local -r commit_shas=("$@")
local -r trail_template_file_name="review_trail.yaml"

# Create a template yaml file
# Create a template yaml file with a trail level generic attestation for each commit
{
cat <<EOF
version: 1
trail:
attestations:
EOF

for commit in "${commits[@]}"; do
echo " - name: ${commit}"
for commit_sha in "${commit_shas[@]}"; do
echo " - name: ${commit_sha}"
echo " type: generic"
done
} > ${trail_template_file_name}

# Begin trail with this template
kosli begin trail ${trail_name} \
--flow=${flow_name} \
--description="$(git log -1 --pretty='%aN - %s')" \
--template-file=${trail_template_file_name}
}

function get_never_alone_attestation_in_trail
function echo_never_alone_attestation_in_trail
{
local -r source_flow=$1; shift
local -r trail_name=$1; shift
local -r attestation_name=$1; shift
local -r curl_output_file=$(mktemp)
local -r source_flow_name=$1; shift
local -r source_trail_name=$1; shift
local -r source_attestation_name=$1; shift
local -r never_alone_json_file_name=$(mktemp)

local -r source_never_alone_attestation_url="${KOSLI_HOST}/api/v2/attestations/${KOSLI_ORG}/${source_flow_name}/trail/${source_trail_name}/${source_attestation_name}"
http_code=$(curl -X 'GET' \
--user ${KOSLI_API_TOKEN}:unused \
"${KOSLI_HOST}/api/v2/attestations/${KOSLI_ORG}/${source_flow}/trail/${trail_name}/${attestation_name}" \
"${source_never_alone_attestation_url}" \
-H 'accept: application/json' \
--output "${curl_output_file}" \
--output "${never_alone_json_file_name}" \
--write-out "%{http_code}" \
--silent)

if [[ ${http_code} -lt 200 || ${http_code} -gt 299 ]] ; then
>&2 cat "${curl_output_file}"
rm "${curl_output_file}"
# Error in curl command so print error and return empty array
>&2 cat "${never_alone_json_file_name}"
echo "[]"
return
fi

cat "$curl_output_file"
rm "${curl_output_file}"
cat "${never_alone_json_file_name}"
}

function get_never_alone_compliance
function set_never_alone_compliance
{
local -r never_alone_data=$1; shift
local pr_data compliant reviews pr_author reviews_length review state review_author


COMPLIANT_STATUS="false"
REASON_FOR_NON_COMPLIANT="Pull-request has not been approved by someone other than pr-author"
pr_data=$(echo "${never_alone_data}" | jq '.user_data.pullRequest')
compliant="false"
reviews=$(echo "${pr_data}" | jq '.reviews')
pr_author=$(echo "${pr_data}" | jq '.author.login')
reviews_length=$(echo "${pr_data}" | jq '.reviews | length')
Expand All @@ -178,70 +179,80 @@ function get_never_alone_compliance
review=$(echo "${pr_data}" | jq ".reviews[$i]")
state=$(echo "$review" | jq ".state")
review_author=$(echo "$review" | jq ".author.login")
if [ "$state" = '"APPROVED"' -a "${review_author}" != "${pr_author}" ]; then
compliant="true"
if [ "$state" == '"APPROVED"' -a "${review_author}" != "${pr_author}" ]; then
COMPLIANT_STATUS="true"
REASON_FOR_NON_COMPLIANT=""
fi
done

echo $compliant
}

function attest_commit_trail_never_alone
{
# Evaluate never-alone-data for this commit (from source commit trail) and attest compliance to this trail
local -r flow_name=$1; shift
local -r trail_name=$1; shift
local -r commit=$1; shift
local -r source_flow=$1; shift
local -r attestation_name=$1; shift
local -r link_trail_name=${commit:0:7}

local link_to_attestation never_alone_data latest_never_alone_data compliant
local -r commit_sha=$1; shift
local -r source_flow_name=$1; shift
local -r source_attestation_name=$1; shift

local -r source_trail_name=${commit_sha:0:7}
local url_to_source_attestation never_alone_data latest_never_alone_data compliant

link_to_attestation="${KOSLI_HOST}/${KOSLI_ORG}/flows/${source_flow}/trails/${link_trail_name}"
never_alone_data=$(get_never_alone_attestation_in_trail ${source_flow} ${link_trail_name} ${attestation_name})
url_to_source_attestation="${KOSLI_HOST}/${KOSLI_ORG}/flows/${source_flow_name}/trails/${source_trail_name}"
never_alone_data=$(echo_never_alone_attestation_in_trail ${source_flow_name} ${source_trail_name} ${source_attestation_name})
if [ "${never_alone_data}" != "[]" ]; then
latest_never_alone_data=$(echo "${never_alone_data}" | jq '.[-1]')
compliant=$(get_never_alone_compliance "${latest_never_alone_data}")
kosli attest generic \
--flow ${flow_name} \
--trail ${trail_name} \
--commit ${commit} \
--name="${commit}" \
--compliant=${compliant} \
--annotate never_alone_data="${link_to_attestation}"
set_never_alone_compliance "${latest_never_alone_data}"
if [ "${COMPLIANT_STATUS}" == "true" ]; then
kosli attest generic \
--flow=${flow_name} \
--trail=${trail_name} \
--name="${commit_sha}" \
--commit=${commit_sha} \
--compliant="true" \
--annotate="never_alone_data=${url_to_source_attestation}"
else
kosli attest generic \
--flow=${flow_name} \
--trail=${trail_name} \
--name="${commit_sha}" \
--commit=${commit_sha} \
--compliant="false" \
--annotate="never_alone_data=${url_to_source_attestation}" \
--annotate="reason_for_non_compliance=${REASON_FOR_NON_COMPLIANT}"
fi
fi
}

function attest_never_alone_trail_to_parent
{
local -r flow_name=$1; shift
local -r trail_name=$1; shift
local -r parent_flow=$1; shift
local -r parent_trail=$1; shift
local -r parent_flow_name=$1; shift
local -r parent_trail_name=$1; shift

never_alone_trail_link="${KOSLI_HOST}/${KOSLI_ORG}/flows/${flow_name}/trails/${trail_name}"
never_alone_trail_url="${KOSLI_HOST}/${KOSLI_ORG}/flows/${flow_name}/trails/${trail_name}"
kosli attest generic \
--flow ${parent_flow} \
--trail ${parent_trail} \
--name never-alone-trail \
--annotate never_alone_trail="${never_alone_trail_link}"
--flow=${parent_flow_name} \
--trail=${parent_trail_name} \
--name=never-alone-trail \
--annotate="never_alone_trail=${never_alone_trail_url}"
}

function main
{
check_arguments "$@"
# Use gh instead of git so we can keep the commit depth of 1. The order are from oldest
# commit to newest
commits=($(gh api repos/:owner/:repo/compare/${BASE_COMMIT}...${CURRENT_COMMIT} -q '.commits[].sha'))
# Use gh instead of git so we can keep the commit depth of 1. The order are from oldest commit to newest
local -r commits=($(gh api repos/:owner/:repo/compare/${START_COMMIT_SHA}...${END_COMMIT_SHA} -q '.commits[].sha'))

begin_trail_with_template ${FLOW_NAME} ${TRAIL_NAME} "${commits[@]}"

for commit in "${commits[@]}"; do
attest_commit_trail_never_alone ${FLOW_NAME} ${TRAIL_NAME} ${commit} ${SOURCE_FLOW} ${SOURCE_ATTESTATION_NAME}
for commit in "${commits[@]}"; do
attest_commit_trail_never_alone ${FLOW_NAME} ${TRAIL_NAME} ${commit} ${SOURCE_FLOW_NAME} ${SOURCE_ATTESTATION_NAME}
done

if [ -n "${PARENT_FLOW}" ]; then
attest_never_alone_trail_to_parent ${FLOW_NAME} ${TRAIL_NAME} ${PARENT_FLOW} ${PARENT_TRAIL}
if [ -n "${PARENT_FLOW_NAME}" ]; then
attest_never_alone_trail_to_parent ${FLOW_NAME} ${TRAIL_NAME} ${PARENT_FLOW_NAME} ${PARENT_TRAIL_NAME}
fi
}

Expand Down

0 comments on commit b80b7c2

Please sign in to comment.