diff --git a/.kokoro/build.cfg b/.kokoro/build.cfg new file mode 100644 index 00000000..59cdfe4c --- /dev/null +++ b/.kokoro/build.cfg @@ -0,0 +1,24 @@ +# -*- protobuffer -*- +# proto-file: google3/devtools/kokoro/config/proto/build.proto +# proto-message: BuildConfig + +build_file: "functions-framework-java/.kokoro/build.sh" +container_properties { + # Use the full image which has Java, Maven, and gcloud CLI pre-installed + docker_image: "us-central1-docker.pkg.dev/kokoro-container-bakery/kokoro/ubuntu/ubuntu2204/full:current" +} + +fileset_artifacts { + name: "artifacts" + # We will copy the built jars to this folder in build.sh for signing + artifact_globs: "artifacts/*" + error_if_missing: true + destinations { + store_attestation: true + gcs { + gcs_root_path: "oss-exit-gate-prod-projects-bucket/ff-releases/mavencentral/attestations" + } + } + generate_sbom_from_fileset: true + generate_attestation: true +} diff --git a/.kokoro/build.sh b/.kokoro/build.sh new file mode 100755 index 00000000..597b5cf3 --- /dev/null +++ b/.kokoro/build.sh @@ -0,0 +1,114 @@ +#!/bin/bash +set -euo pipefail + +# The repo is cloned to $KOKORO_ARTIFACTS_DIR/git/functions-framework-java +REPO_DIR="${KOKORO_ARTIFACTS_DIR}/git/functions-framework-java" +cd "${REPO_DIR}" + +# ============================================================================== +# 1. Configure Airlock and AR Credentials +# ============================================================================== +# Get OAuth token from GCE metadata server inside Kokoro VM +MAVEN_TOKEN=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google" | grep -oP '"access_token":"\K[^"]+') + +# Create a temporary settings.xml to configure Airlock mirror and AR auth +cat > settings.xml < + + + + airlock-mirror + Airlock Maven Central mirror + https://us-maven.pkg.dev/artifact-foundry-prod/maven-3p-trusted + * + + + + + + airlock-mirror + oauth2accesstoken + ${MAVEN_TOKEN} + + + + exit-gate-ar + oauth2accesstoken + ${MAVEN_TOKEN} + + + +EOF + +# ============================================================================== +# 2. Retrieve GPG keys from Secret Manager +# ============================================================================== +GPG_KEYRING="${KOKORO_ARTIFACTS_DIR}/gpg-keyring" +GPG_PASSPHRASE_FILE="${KOKORO_ARTIFACTS_DIR}/gpg-passphrase" + +# Read names from environment variables injected by Louhi +PROJECT_ID="${_LOUHI_SECRET_PROJECT_ID}" +KEYRING_NAME="${_LOUHI_GPG_KEYRING_SECRET_NAME}" +PASSPHRASE_NAME="${_LOUHI_GPG_PASSPHRASE_SECRET_NAME}" + +echo "Fetching secrets from project: ${PROJECT_ID}" +gcloud secrets versions access latest --secret="${KEYRING_NAME}" --project="${PROJECT_ID}" > "${GPG_KEYRING}" +gcloud secrets versions access latest --secret="${PASSPHRASE_NAME}" --project="${PROJECT_ID}" > "${GPG_PASSPHRASE_FILE}" + +export GPG_TTY=$(tty) +export GPG_PASSPHRASE=$(cat "${GPG_PASSPHRASE_FILE}") +export GNUPGHOME=/tmp/gpg +mkdir -p "${GNUPGHOME}" +gpg --batch --import "${GPG_KEYRING}" + +# ============================================================================== +# 3. Build, Sign, and Deploy +# ============================================================================== +# Detect which package to build based on the Louhi trigger tag +if [[ -n "${_LOUHI_REF_NAME:-}" ]]; then + echo "Triggered by Louhi tag: ${_LOUHI_REF_NAME}" + if [[ "${_LOUHI_REF_NAME}" == *functions-framework-api* ]]; then + PACKAGE_DIR="functions-framework-api" + elif [[ "${_LOUHI_REF_NAME}" == *function-maven-plugin* ]]; then + PACKAGE_DIR="function-maven-plugin" + elif [[ "${_LOUHI_REF_NAME}" == *java-function-invoker* ]]; then + PACKAGE_DIR="invoker" + else + echo "Unknown tag format: ${_LOUHI_REF_NAME}. Defaulting to invoker." + PACKAGE_DIR="invoker" + fi +else + # Fallback for manual/non-tag builds (e.g. testing) + echo "No Louhi tag detected. Falling back to KOKORO_JOB_NAME detection." + if [[ $KOKORO_JOB_NAME == *"function-maven-plugin"* ]]; then + PACKAGE_DIR="function-maven-plugin" + elif [[ $KOKORO_JOB_NAME == *"functions-framework-api"* ]]; then + PACKAGE_DIR="functions-framework-api" + else + PACKAGE_DIR="invoker" + fi +fi + +echo "Building package in directory: ${PACKAGE_DIR}" +cd "${PACKAGE_DIR}" + +# Run maven deploy using the temporary settings.xml +# We use altDeploymentRepository to override the deploy target without editing pom.xml +mvn clean deploy -B \ + -P sonatype-oss-release \ + --settings=../settings.xml \ + -DaltDeploymentRepository=exit-gate-ar::https://us-maven.pkg.dev/oss-exit-gate-prod/ff-releases--mavencentral \ + -Dgpg.executable=gpg \ + -Dgpg.passphrase="${GPG_PASSPHRASE}" \ + -Dgpg.homedir="${GNUPGHOME}" + +# ============================================================================== +# 4. Copy artifacts to 'artifacts/' folder for Kokoro Attestation Generation +# ============================================================================== +ARTIFACTS_DIR="${REPO_DIR}/artifacts" +mkdir -p "${ARTIFACTS_DIR}" + +# Copy target jars and poms (excluding test jars) to be captured by build.cfg +find target/ -maxdepth 1 -name "*.jar" -o -name "*.pom" | grep -v "test" | xargs -I {} cp {} "${ARTIFACTS_DIR}/" diff --git a/.kokoro/release.cfg b/.kokoro/release.cfg index 08d0ac9f..c617e165 100644 --- a/.kokoro/release.cfg +++ b/.kokoro/release.cfg @@ -1,30 +1,23 @@ +# -*- protobuffer -*- +# proto-file: google3/devtools/kokoro/config/proto/build.proto +# proto-message: BuildConfig + build_file: "functions-framework-java/.kokoro/release.sh" +container_properties { + docker_image: "us-docker.pkg.dev/artifact-foundry-prod/docker-3p-trusted/ubuntu:22.04" +} -before_action { - fetch_keystore { - keystore_resource { - keystore_config_id: 75669 - keyname: "functions-framework-java-release-bot-sonatype-password" - } - keystore_resource { - keystore_config_id: 75669 - keyname: "functions-framework-release-sonatype-central-portal-username" - } - keystore_resource { - keystore_config_id: 75669 - keyname: "functions-framework-release-sonatype-central-portal-password" - } - keystore_resource { - keystore_config_id: 70247 - keyname: "maven-gpg-pubkeyring" - } - keystore_resource { - keystore_config_id: 70247 - keyname: "maven-gpg-keyring" - } - keystore_resource { - keystore_config_id: 70247 - keyname: "maven-gpg-passphrase" +fileset_artifacts { + name: "manifest" + artifact_globs: "manifest.json" + error_if_missing: true + destinations { + store_attestation: false + gcs { + gcs_root_path: "oss-exit-gate-prod-projects-bucket/ff-releases/mavencentral/manifests" + populate_content_type: true } } + generate_sbom_from_fileset: false + generate_attestation: false } diff --git a/.kokoro/release.sh b/.kokoro/release.sh old mode 100644 new mode 100755 index b85e6003..58b865a6 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -1,84 +1,10 @@ #!/bin/bash +set -euo pipefail -# Stop execution when any command fails. -set -e +cd "${KOKORO_ARTIFACTS_DIR}" -# update the Maven version to 3.9.11 -pushd /usr/local -wget https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.tar.gz -tar -xvzf apache-maven-3.9.11-bin.tar.gz apache-maven-3.9.11 -rm -f /usr/local/apache-maven -ln -s /usr/local/apache-maven-3.9.11 /usr/local/apache-maven -rm apache-maven-3.9.11-bin.tar.gz -popd - - -# Get secrets from keystore and set and environment variables. -setup_environment_secrets() { - export GPG_TTY=$(tty) - export GPG_PASSPHRASE=$(cat ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-passphrase) - - # Add the key ring files to $GNUPGHOME to verify the GPG credentials. - export GNUPGHOME=/tmp/gpg - mkdir $GNUPGHOME - mv ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-pubkeyring $GNUPGHOME/pubring.gpg - mv ${KOKORO_KEYSTORE_DIR}/70247_maven-gpg-keyring $GNUPGHOME/secring.gpg - gpg -k -} - -create_settings_xml_file() { - echo " - - - - true - - - ${GPG_PASSPHRASE} - - - - - - sonatype-central-portal - $(cat "${KOKORO_KEYSTORE_DIR}/75669_functions-framework-release-sonatype-central-portal-username") - $(cat "${KOKORO_KEYSTORE_DIR}/75669_functions-framework-release-sonatype-central-portal-password") - - -" > $1 +cat > manifest.json <<'EOF' +{ + "publish_all": true } - -setup_environment_secrets - -# Pick the right package to release based on the Kokoro job name. -cd ${KOKORO_ARTIFACTS_DIR}/github/functions-framework-java -create_settings_xml_file "settings.xml" -echo "KOKORO_JOB_NAME=${KOKORO_JOB_NAME}" -if [[ $KOKORO_JOB_NAME == *"function-maven-plugin"* ]]; then - cd function-maven-plugin -elif [[ $KOKORO_JOB_NAME == *"functions-framework-api"* ]]; then - cd functions-framework-api -else - cd invoker -fi -echo "pwd=$(pwd)" - -# Make sure `JAVA_HOME` is set and using jdk17. -JDK_VERSION=17 -apt-get update -# Install new JDK version -apt-get install -y openjdk-"${JDK_VERSION}"-jdk -export JAVA_HOME="$(update-java-alternatives -l | grep "1.${JDK_VERSION}" | head -n 1 | tr -s " " | cut -d " " -f 3)" -echo "JAVA_HOME=$JAVA_HOME" - -SUPPRESS_LOGS='-q' -if [[ -n "${ENABLE_LOGS}" ]]; then - SUPPRESS_LOGS='' -fi - -mvn clean deploy -B ${SUPPRESS_LOGS} \ - -P sonatype-oss-release \ - --settings=../settings.xml \ - -Dgpg.executable=gpg \ - -Dgpg.passphrase=${GPG_PASSPHRASE} \ - -Dgpg.homedir=${GNUPGHOME} +EOF