Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test for Gradle builder #270

Merged
merged 15 commits into from
Aug 17, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
on:
schedule:
- cron: "0 6 * * *"
workflow_dispatch:
inputs:
trigger_build:
description: "internal: do not check"
required: false
default: false
type: boolean

permissions: read-all

concurrency: "e2e-gradle-workflow_dispatch-main-default-slsa3"

env:
# TODO(#263): create dedicated token
GH_TOKEN: ${{ github.token }}
AdamKorcz marked this conversation as resolved.
Show resolved Hide resolved
ISSUE_REPOSITORY: slsa-framework/slsa-github-generator

jobs:
# Bootstrap
################################################################################

bootstrap:
runs-on: ubuntu-latest
if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && !inputs.trigger_build)
permissions:
contents: write
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- env:
PACKAGE_DIR: ./e2e/gradle/workflow_dispatch
run: ./.github/workflows/scripts/e2e-gradle-push.sh

if-bootstrap-failed:
runs-on: ubuntu-latest
needs: [bootstrap]
if: always() && (github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && !inputs.trigger_build)) && needs.bootstrap.result != 'success'
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- run: ./.github/workflows/scripts/e2e-report-failure.sh

# Main workflow
################################################################################
# Shim determines if the rest of the workflow should run.
# NOTE: it should only use the `if` to determine this and all downstream jobs
# should depend on this job.
shim:
# NOTE: this must be kept in sync with the if-failed job.
if: github.event_name == 'workflow_dispatch' && inputs.trigger_build
runs-on: ubuntu-latest
steps:
- run: |
echo "event: ${GITHUB_EVENT_NAME}"
echo "ref: ${GITHUB_REF}"

build:
#needs: [shim] uncomment before merging
permissions:
id-token: write # For signing.
contents: read # For repo checkout of private repos.
actions: read # For getting workflow run on private repos.
uses: slsa-framework/slsa-github-generator/.github/workflows/builder_gradle_slsa3.yml@main
with:
directory: ./e2e/gradle/workflow_dispatch
artifact-list: build/libs/workflow_dispatch-GRADLE_VERSION.jar,build/libs/workflow_dispatch-GRADLE_VERSION-javadoc.jar,build/libs/workflow_dispatch-GRADLE_VERSION-sources.jar

verify:
runs-on: ubuntu-latest
needs: [build]
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- uses: slsa-framework/slsa-github-generator/actions/gradle/secure-download-attestations@main
with:
name: "${{ needs.build.outputs.provenance-download-name }}"
sha256: "${{ needs.build.outputs.provenance-download-sha256 }}"
path: slsa-attestations
- uses: slsa-framework/slsa-github-generator/actions/gradle/secure-download-target@main
with:
name: build
sha256: "${{ needs.build.outputs.target-download-sha256 }}"
path: ./
# NOTE: To build slsa-verifier in e2e.gradle.default.verify.sh
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
with:
go-version: "1.18"
- env:
PROVENANCE_DIR: "slsa-attestations/${{ needs.build.outputs.provenance-download-name }}"
EXPECTED_ARTIFACT_OUTPUT: "Hello world!"
PROJECT_DIR: "e2e/gradle/workflow_dispatch"
run: ./.github/workflows/scripts/e2e.gradle.default.verify.sh
if-succeeded:
AdamKorcz marked this conversation as resolved.
Show resolved Hide resolved
runs-on: ubuntu-latest
needs: [build, verify]
if: needs.build.result == 'success' && needs.verify.result == 'success'
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- run: ./.github/workflows/scripts/e2e-report-success.sh

if-failed:
runs-on: ubuntu-latest
needs: [build, verify]
if: always() && github.event_name == 'workflow_dispatch' && inputs.trigger_build && (needs.build.result != 'success' || needs.verify.result != 'success')
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- run: ./.github/workflows/scripts/e2e-report-failure.sh
131 changes: 131 additions & 0 deletions .github/workflows/scripts/e2e-gradle-push.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#!/usr/bin/env bash
set -euo pipefail

# shellcheck source=/dev/null
source "./.github/workflows/scripts/e2e-utils.sh"

# This script bumps the gradle package's version number, commits it, and pushes to
# the repository.

branch=$(e2e_this_branch)

# Script Inputs
GITHUB_OUTPUT=${GITHUB_OUTPUT:-}
GITHUB_REPOSITORY=${GITHUB_REPOSITORY:-}
GITHUB_SHA=${GITHUB_SHA:-}
GITHUB_WORKFLOW=${GITHUB_WORKFLOW:-}
GH_TOKEN=${GH_TOKEN:-}
PACKAGE_DIR=${PACKAGE_DIR:-} # specified in the e2e test yaml

# NOTE: We can't simply push from $branch because it is occaisonally reset to
AdamKorcz marked this conversation as resolved.
Show resolved Hide resolved
# the main branch. We need to maintain the version number in gradle.build.kts
# because you cannot overwrite a version in gradle. Instead we commit to main,
# set the tag, reset $branch and push both main and $branch.
gh repo clone "${GITHUB_REPOSITORY}" -- -b main
repo_name=$(echo "$GITHUB_REPOSITORY" | cut -d '/' -f2)
cd ./"$repo_name"

git config --global user.name github-actions
git config --global user.email github-actions@github.com

# Set the remote url to authenticate using the token.
git remote set-url origin "https://github-actions:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"

package_dir="${PACKAGE_DIR}" # specified in the e2e test yaml
cd "${package_dir}"

# Get the artifact tag
artifact_tag=$(./gradlew properties -q | grep "version:" | awk '{print $2}')

# Bumps the version
new_version() {
current_tag=$1
release_major=$(version_major "$current_tag")
release_minor=$(version_minor "$current_tag")
release_patch=$(version_patch "$current_tag")

# These if-statements are sorted by likelihood
if [[ $release_patch != "99" ]]; then
# Only need to bump the patch
release_patch=$((release_patch+1))
elif [[ $release_patch = "99" && $release_minor != "99" ]]; then
# Need to bump minor
release_minor=$(($release_minor+1))
release_patch="0"
elif [[ $release_patch = "99" && $release_minor = "99" ]]; then
# Need to bump major
release_major=$(($release_major+1))
release_minor="0"
release_patch="0"
fi
echo $release_major.$release_minor.$release_patch
}

next_tag=$(new_version "${artifact_tag}")

# Update the version in build.gradle.kts
sed -i "s/version = \"${artifact_tag}\"/version = \"${next_tag}\"/g" ./build.gradle.kts
cd -

# Commit the new version.
git commit -m "${GITHUB_WORKFLOW}" "${package_dir}/build.gradle.kts" "${package_dir}/build.gradle.kts"

# If this is an e2e test for a tag, then tag the commit and push it.
this_event=$(e2e_this_event)
echo "this_event: ${this_event}"
if [ "${this_event}" == "tag" ] || [ "${this_event}" == "create" ]; then
git tag "${tag}"
fi

git remote -v
git branch
pwd
if [ "${branch}" != "main" ]; then
# Reset branch1 and push the new version.
git checkout -b "${branch}"
if [ "${this_event}" == "tag" ] || [ "${this_event}" == "create" ]; then
git push --set-upstream origin "${branch}" "${tag}" -f
else
git push --set-upstream origin "${branch}" -f
fi
git checkout main

# Update a dummy file to avoid https://github.com/slsa-framework/example-package/issues/44
date >./e2e/dummy
git add ./e2e/dummy
git commit -m "sync'ing branch1 - $(cat ./e2e/dummy)"
git push origin main
else
if [ "${this_event}" == "tag" ] || [ "${this_event}" == "create" ]; then
# TODO(#213): push tag separately until bug is fixed.
# NOTE: If there is a concurrent update to main we want it to fail here
# without pushing the tag because we will lose the changes to main.
git push origin main
git push origin "${tag}"
else
git push origin main
fi
fi

# If this is a test for a release event, create the release.
if [ "${this_event}" == "release" ]; then
this_file=$(e2e_this_file)
data_file=$(mktemp)
cat <<EOF >"${data_file}"
**E2E release creation**:
Tag: ${tag}
Branch: ${branch}
Commit: ${GITHUB_SHA}
Caller file: ${this_file}
EOF

gh release create "${tag}" --notes-file "${data_file}" --target "${branch}"
fi

if [ "${this_event}" == "workflow_dispatch" ]; then
this_file=$(e2e_this_file)
curl -s -X POST -H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${GITHUB_REPOSITORY}/actions/workflows/${this_file}/dispatches" \
-d "{\"ref\":\"${branch}\",\"inputs\":{\"trigger_build\": true}}" \
-H "Authorization: token ${GH_TOKEN}"
fi
57 changes: 57 additions & 0 deletions .github/workflows/scripts/e2e.gradle.default.verify.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env bash

# shellcheck source=/dev/null
source "./.github/workflows/scripts/e2e-verify.common.sh"

# Input variables
EXPECTED_ARTIFACT_OUTPUT=${EXPECTED_ARTIFACT_OUTPUT:-}
PROVENANCE_DIR=${PROVENANCE_DIR:-}
GITHUB_REF_NAME=${GITHUB_REF_NAME:-}
GITHUB_REF=${GITHUB_REF:-}
GITHUB_REF_TYPE=${GITHUB_REF_TYPE:-}
RUNNER_DEBUG=${RUNNER_DEBUG:-}
if [[ -n "${RUNNER_DEBUG}" ]]; then
set -x
fi

cp -r "slsa-attestations" "${PROJECT_DIR}/"
cp -r build "${PROJECT_DIR}/"
cd "${PROJECT_DIR}"

artifact_version=$(./gradlew properties -q | grep "version:" | awk '{print $2}')
artifact_id=$(./gradlew properties -q | grep "name:" | awk '{print $2}')
artifact_name="${artifact_id}-${artifact_version}.jar"
provenance="${PROVENANCE_DIR}/${artifact_name}.build.slsa"

go env -w GOFLAGS=-mod=mod

laurentsimon marked this conversation as resolved.
Show resolved Hide resolved
verify_provenance_content() {
local attestation
attestation=$(jq -r '.dsseEnvelope.payload' "${provenance}" | base64 -d)

# Run the artifact and verify the output is correct
artifact_output=$(java -jar build/libs/"${artifact_name}")
expected_artifact_output="${EXPECTED_ARTIFACT_OUTPUT}"
e2e_assert_eq "${artifact_output}" "${expected_artifact_output}" "The output from the artifact should be '${expected_artifact_output}' but was '${artifact_output}'"

# Verify the content of the attestation
e2e_verify_predicate_subject_name "${attestation}" "${artifact_name}"
e2e_verify_predicate_v1_runDetails_builder_id "${attestation}" "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/builder_gradle_slsa3.yml@refs/heads/main"
e2e_verify_predicate_v1_buildDefinition_buildType "${attestation}" "https://github.com/slsa-framework/slsa-github-generator/delegator-generic@v0"
laurentsimon marked this conversation as resolved.
Show resolved Hide resolved
}

this_file=$(e2e_this_file)
branch=$(echo "$this_file" | cut -d '.' -f4)
echo "branch is $branch"
echo "GITHUB_REF_NAME: $GITHUB_REF_NAME"
echo "GITHUB_REF_TYPE: $GITHUB_REF_TYPE"
echo "GITHUB_REF: $GITHUB_REF"
echo "DEBUG: file is $this_file"
echo "PROVENANCE is: ${provenance}"

export SLSA_VERIFIER_TESTING="true"

# Verify provenance content.
verify_provenance_content

e2e_run_verifier_all_releases "HEAD"
21 changes: 21 additions & 0 deletions e2e/gradle/workflow_dispatch/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* This file was generated by the Gradle 'init' task.
*/

import java.io.File

group = "io.github.adamkorcz"
version = "0.1.47"
AdamKorcz marked this conversation as resolved.
Show resolved Hide resolved
description = "Adams test java project"
java.sourceCompatibility = JavaVersion.VERSION_1_8

java {
withSourcesJar()
withJavadocJar()
}

tasks.withType<Jar> {
manifest {
attributes["Main-Class"] = "hello.HelloWorld"
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading