diff --git a/.gitea/workflows/release.yaml b/.gitea/workflows/release.yaml index b3b9c08..0eb00b6 100644 --- a/.gitea/workflows/release.yaml +++ b/.gitea/workflows/release.yaml @@ -1,5 +1,10 @@ name: Release +env: + GPG_PRIVATE_KEY_FILE: ${{ runner.temp }}/private.key + GPG_PRIVATE_KEY_FINGERPRINT: ${{ vars.GPG_PRIVATE_KEY_FINGERPRINT }} + GPG_PRIVATE_KEY_PASSPHRASE_FILE: ${{ runner.temp }}/passphrase.txt + on: push: tags: @@ -7,14 +12,58 @@ on: jobs: publish-chart: - container: - image: docker.io/volkerraschek/helm:3.19.2 runs-on: ubuntu-latest steps: - - name: Install packages via apk + - uses: volker-raschek/cosign-installer@v4.1.2-rc4 + with: + cosign-release: "v3.0.6" # renovate: datasource=github-tags depName=sigstore/cosign + + - uses: azure/setup-helm@v5.0.0 + with: + version: "v4.1.4" # renovate: datasource=github-tags depName=helm/helm + + - name: Install helm plugins + env: + HELM_SIGSTORE_VERSION: "0.3.0" # renovate: datasource=github-tags depName=sigstore/helm-sigstore extractVersion='^v(?\d+\.\d+\.\d+)$' + HELM_SCHEMA_VALUES_VERSION: "2.4.0" # renovate: datasource=github-tags depName=losisin/helm-values-schema-json extractVersion='^v(?\d+\.\d+\.\d+)$' + HELM_UNITTEST_VERSION: "1.0.3" # renovate: datasource=github-tags depName=helm-unittest/helm-unittest extractVersion='^v(?\d+\.\d+\.\d+)$' run: | - apk update - apk add git npm jq yq + helm plugin install --verify=false https://github.com/sigstore/helm-sigstore.git --version "${HELM_SIGSTORE_VERSION}" 1> /dev/null + helm plugin install --verify=false https://github.com/losisin/helm-values-schema-json.git --version "${HELM_SCHEMA_VALUES_VERSION}" 1> /dev/null + helm plugin install --verify=false https://github.com/helm-unittest/helm-unittest.git --version "${HELM_UNITTEST_VERSION}" 1> /dev/null + helm plugin list + + - name: GPG configuration + env: + GPG_PRIVATE_KEY_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSPHRASE }} + GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} + run: | + # Configure GPG and GPG Agent + mkdir --parents "${HOME}/.gnupg" + chmod 0700 "${HOME}/.gnupg" + + cat > "${HOME}/.gnupg/gpg.conf" < "${HOME}/.gnupg/gpg-agent.conf" < "${GPG_PRIVATE_KEY_PASSPHRASE_FILE}" <<< "${GPG_PRIVATE_KEY_PASSPHRASE}" + cat 1> "${GPG_PRIVATE_KEY_FILE}" <<< "${GPG_PRIVATE_KEY}" + gpg --batch --yes --passphrase-fd 0 --import "${GPG_PRIVATE_KEY_FILE}" <<< "${GPG_PRIVATE_KEY_PASSPHRASE}" + + # Export GPG keyring + gpg --batch --yes --export "${GPG_PRIVATE_KEY_FINGERPRINT}" 1> "${HOME}/.gnupg/pubring.gpg" + gpg --batch --yes --passphrase-fd 0 --export-secret-keys "${GPG_PRIVATE_KEY_FINGERPRINT}" 1> "${HOME}/.gnupg/secring.gpg" <<< "${GPG_PRIVATE_KEY_PASSPHRASE}" - uses: actions/checkout@v6.0.2 with: @@ -28,9 +77,10 @@ jobs: - name: Extract meta information run: | + echo "GITEA_SERVER_HOSTNAME=$(echo "${GITHUB_SERVER_URL}" | cut --delimiter '/' --fields 3)" >> $GITHUB_ENV echo "PACKAGE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV - echo "REPOSITORY_NAME=$(echo ${GITHUB_REPOSITORY} | cut -d '/' -f 2 | sed --regexp-extended 's/-charts?//g')" >> $GITHUB_ENV - echo "REPOSITORY_OWNER=$(echo ${GITHUB_REPOSITORY} | cut -d '/' -f 1)" >> $GITHUB_ENV + echo "REPOSITORY_NAME=$(echo ${GITHUB_REPOSITORY} | cut --delimiter '/' --fields 2 | sed --regexp-extended 's/-charts?//g')" >> $GITHUB_ENV + echo "REPOSITORY_OWNER=$(echo ${GITHUB_REPOSITORY} | cut --delimiter '/' --fields 1)" >> $GITHUB_ENV - name: Update Helm Chart version in README.md run: sed -i -E "s/^CHART_VERSION=.*/CHART_VERSION=${PACKAGE_VERSION}/g" README.md @@ -38,24 +88,76 @@ jobs: - name: Package chart run: | helm dependency build - helm package --version "${PACKAGE_VERSION}" ./ + helm package \ + --sign \ + --key "$(gpg --with-colons --list-keys "${GPG_PRIVATE_KEY_FINGERPRINT}" | grep uid | cut --delimiter ':' --fields 10)" \ + --keyring "${HOME}/.gnupg/secring.gpg" \ + --passphrase-file "${GPG_PRIVATE_KEY_PASSPHRASE_FILE}" \ + --version "${PACKAGE_VERSION}" ./ - - name: Upload Chart to ChartMuseum + - uses: docker/login-action@v4.1.0 + with: + registry: ${{ github.server_url }} + username: ${{ github.repository_owner }} + password: ${{ secrets.GIT_CRYPTIC_SYSTEMS_PACKAGE_REGISTRY_TOKEN }} + + - name: Upload Chart to Gitea (OCI) env: + COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} + COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} + run: | + helm push ${REPOSITORY_NAME}-${PACKAGE_VERSION}.tgz oci://${GITEA_SERVER_HOSTNAME}/${REPOSITORY_OWNER} + cosign sign --yes --upload=true --key=env://COSIGN_PRIVATE_KEY ${GITEA_SERVER_HOSTNAME}/${REPOSITORY_OWNER}/${REPOSITORY_NAME}:${PACKAGE_VERSION} + + - name: Upload Chart to Gitea (Helm) + env: + GITEA_REGISTRY_TOKEN: ${{ secrets.GIT_CRYPTIC_SYSTEMS_PACKAGE_REGISTRY_TOKEN }} + run: | + curl \ + --fail \ + --show-error \ + --request POST \ + --user "${REPOSITORY_OWNER}:${GITEA_REGISTRY_TOKEN}" \ + --upload-file "${REPOSITORY_NAME}-${PACKAGE_VERSION}.tgz" \ + https://${GITEA_SERVER_HOSTNAME}/api/packages/${REPOSITORY_OWNER}/helm/api/charts + + # NOTE: + # Gitea does currently not support uploading Helm chart provenance files, so we skip this step for now. Once + # Gitea supports this, we can simply uncomment the following lines to upload the provenance file as well. + # + # https://github.com/helm/helm/issues/31866 + # + # if [ -f "${REPOSITORY_NAME}-${PACKAGE_VERSION}.tgz.prov" ]; then + # curl \ + # --fail \ + # --show-error \ + # --request POST \ + # --user "${CHARTMUSEUM_USERNAME}:${CHARTMUSEUM_PASSWORD}" \ + # --upload-file "${REPOSITORY_NAME}-${PACKAGE_VERSION}.tgz.prov" \ + # https://${GITEA_SERVER_HOSTNAME}/api/packages/${REPOSITORY_OWNER}/helm/api/prov + # fi + + - name: Upload Chart to Chartmuseum (Helm) + env: + CHARTMUSEUM_HOSTNAME: ${{ vars.CHARTMUSEUM_HOSTNAME }} + CHARTMUSEUM_USERNAME: ${{ secrets.CHARTMUSEUM_USERNAME }} CHARTMUSEUM_PASSWORD: ${{ secrets.CHARTMUSEUM_PASSWORD }} CHARTMUSEUM_REPOSITORY: ${{ vars.CHARTMUSEUM_REPOSITORY }} - CHARTMUSEUM_USERNAME: ${{ secrets.CHARTMUSEUM_USERNAME }} - CHARTMUSEUM_HOSTNAME: ${{ vars.CHARTMUSEUM_HOSTNAME }} run: | - helm repo add --username ${CHARTMUSEUM_USERNAME} --password ${CHARTMUSEUM_PASSWORD} chartmuseum https://${CHARTMUSEUM_HOSTNAME}/${CHARTMUSEUM_REPOSITORY} - helm cm-push ${REPOSITORY_NAME}-${PACKAGE_VERSION}.tgz chartmuseum - helm repo remove chartmuseum + curl \ + --fail \ + --show-error \ + --request POST \ + --user "${CHARTMUSEUM_USERNAME}:${CHARTMUSEUM_PASSWORD}" \ + --upload-file "${REPOSITORY_NAME}-${PACKAGE_VERSION}.tgz" \ + https://${CHARTMUSEUM_HOSTNAME}/api/${CHARTMUSEUM_REPOSITORY}/charts - - name: Upload Chart to Gitea - env: - GITEA_PACKAGE_REGISTRY_TOKEN: ${{ secrets.GIT_CRYPTIC_SYSTEMS_PACKAGE_REGISTRY_TOKEN }} - GITEA_SERVER_URL: ${{ github.server_url }} - run: | - helm repo add --username ${REPOSITORY_OWNER} --password ${GITEA_PACKAGE_REGISTRY_TOKEN} gitea ${GITEA_SERVER_URL}/api/packages/${REPOSITORY_OWNER}/helm - helm cm-push ${REPOSITORY_NAME}-${PACKAGE_VERSION}.tgz gitea - helm repo remove gitea + if [ -f "${REPOSITORY_NAME}-${PACKAGE_VERSION}.tgz.prov" ]; then + curl \ + --fail \ + --show-error \ + --request POST \ + --user "${CHARTMUSEUM_USERNAME}:${CHARTMUSEUM_PASSWORD}" \ + --upload-file ${REPOSITORY_NAME}-${PACKAGE_VERSION}.tgz.prov \ + https://${CHARTMUSEUM_HOSTNAME}/api/${CHARTMUSEUM_REPOSITORY}/prov + fi diff --git a/.gitignore b/.gitignore index 712fa4a..f7ffbb9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ charts +cosign* node_modules target !values.yaml