# Do not edit these workflows directly as the changes made will be overwritten. # Instead, edit the template '.github/workflows/templates/release.yml.jinja' --- name: Release run-name: "Release (branch: ${{ github.ref_name }}; version: ${{ inputs.salt-version }})" on: workflow_dispatch: inputs: salt-version: type: string required: true description: > The Salt version to get from staging to publish the release. (DO NOT prefix the version with a v, ie, 3006.0 NOT v3006.0). skip-salt-pkg-download-test-suite: type: boolean default: false description: Skip running the Salt packages download test suite. env: COLUMNS: 190 CACHE_SEED: SEED-1 # Bump the number to invalidate all caches RELENV_DATA: "${{ github.workspace }}/.relenv" PIP_DISABLE_PIP_VERSION_CHECK: "1" RAISE_DEPRECATIONS_RUNTIME_ERRORS: "1" permissions: contents: write # To be able to publish the release concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.repository }} cancel-in-progress: false jobs: check-requirements: name: Check Requirements runs-on: ubuntu-22.04 environment: release-check steps: - name: Check For Admin Permission uses: actions-cool/check-user-permission@v2 with: require: admin username: ${{ github.triggering_actor }} prepare-workflow: name: Prepare Workflow Run runs-on: - linux-x86_64 env: USE_S3_CACHE: 'false' environment: release needs: - check-requirements outputs: salt-version: ${{ steps.setup-salt-version.outputs.salt-version }} cache-seed: ${{ steps.set-cache-seed.outputs.cache-seed }} latest-release: ${{ steps.get-salt-releases.outputs.latest-release }} releases: ${{ steps.get-salt-releases.outputs.releases }} nox-archive-hash: ${{ steps.nox-archive-hash.outputs.nox-archive-hash }} config: ${{ steps.workflow-config.outputs.config }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # Full clone to also get the tags to get the right salt version - name: Set up Python 3.10 uses: actions/setup-python@v5 with: python-version: "3.10" - name: Setup Python Tools Scripts uses: ./.github/actions/setup-python-tools-scripts with: cache-prefix: ${{ env.CACHE_SEED }} - name: Pretty Print The GH Actions Event run: tools ci print-gh-event - name: Setup Salt Version id: setup-salt-version uses: ./.github/actions/setup-salt-version with: salt-version: "${{ inputs.salt-version }}" validate-version: true - name: Check Existing Releases env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | tools pkg repo confirm-unreleased --repository ${{ github.repository }} ${{ steps.setup-salt-version.outputs.salt-version }} if [ "${{ github.event.repository.private }}" = "true" ]; then tools pkg repo confirm-unreleased --repository saltstack/salt ${{ steps.setup-salt-version.outputs.salt-version }} fi - name: Check Release Staged env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | tools pkg repo confirm-staged --repository ${{ github.repository }} ${{ steps.setup-salt-version.outputs.salt-version }} - name: Get Salt Releases id: get-salt-releases env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | tools ci get-releases - name: Set Cache Seed Output id: set-cache-seed run: | tools ci define-cache-seed ${{ env.CACHE_SEED }} - name: Get Hash For Nox Tarball Cache id: nox-archive-hash run: | echo "nox-archive-hash=${{ hashFiles('requirements/**/*.txt', 'cicd/golden-images.json', 'noxfile.py', 'pkg/common/env-cleanup-rules.yml', '.github/workflows/build-deps-ci-action.yml') }}" | tee -a "$GITHUB_OUTPUT" - name: Define workflow config id: workflow-config run: | tools ci workflow-config${{ inputs.skip-salt-pkg-download-test-suite && ' --skip-pkg-download-tests' || '' }} ${{ steps.setup-salt-version.outputs.salt-version }} ${{ github.event_name }} changed-files.json download-onedir-artifact: name: Download Staging Onedir Artifact runs-on: - linux-x86_64 env: USE_S3_CACHE: 'true' environment: release needs: - prepare-workflow strategy: fail-fast: false matrix: include: - platform: linux arch: x86_64 - platform: linux arch: arm64 - platform: windows arch: amd64 - platform: windows arch: x86 - platform: macos arch: x86_64 - platform: macos arch: arm64 steps: - uses: actions/checkout@v4 - name: Setup Python Tools Scripts uses: ./.github/actions/setup-python-tools-scripts with: cache-prefix: ${{ needs.prepare-workflow.outputs.cache-seed }} - name: Get Salt Project GitHub Actions Bot Environment run: | TOKEN=$(curl -sS -f -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 30") SPB_ENVIRONMENT=$(curl -sS -f -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/tags/instance/spb:environment) echo "SPB_ENVIRONMENT=$SPB_ENVIRONMENT" >> "$GITHUB_ENV" - name: Download Onedir Tarball Artifact run: | tools release download-onedir-artifact --platform=${{ matrix.platform }} --arch=${{ matrix.arch }} ${{ inputs.salt-version }} - name: Upload Onedir Tarball as an Artifact uses: actions/upload-artifact@v4 with: name: salt-${{ inputs.salt-version }}-onedir-${{ matrix.platform }}-${{ matrix.arch }}.tar.xz path: artifacts/salt-${{ inputs.salt-version }}-onedir-${{ matrix.platform }}-${{ matrix.arch }}.tar.xz* retention-days: 7 if-no-files-found: error build-ci-deps: name: CI Deps needs: - prepare-workflow - download-onedir-artifact uses: ./.github/workflows/build-deps-ci-action.yml with: nox-session: ci-test-onedir nox-version: 2022.8.7 python-version: "3.10" salt-version: "${{ needs.prepare-workflow.outputs.salt-version }}" cache-prefix: ${{ needs.prepare-workflow.outputs.cache-seed }}|3.10.15 nox-archive-hash: "${{ needs.prepare-workflow.outputs.nox-archive-hash }}" matrix: ${{ toJSON(fromJSON(needs.prepare-workflow.outputs.config)['build-matrix']) }} linux_arm_runner: ${{ fromJSON(needs.prepare-workflow.outputs.config)['linux_arm_runner'] }} backup: name: Backup runs-on: - linux-x86_64 needs: - prepare-workflow env: USE_S3_CACHE: 'true' environment: release outputs: backup-complete: ${{ steps.backup.outputs.backup-complete }} steps: - name: Clone The Salt Repository uses: actions/checkout@v4 - name: Setup Rclone uses: AnimMouse/setup-rclone@v1 with: version: v1.61.1 - name: Setup Python Tools Scripts uses: ./.github/actions/setup-python-tools-scripts with: cache-prefix: ${{ needs.prepare-workflow.outputs.cache-seed }} - name: Backup Previous Releases id: backup run: | tools pkg repo backup-previous-releases publish-repositories: name: Publish Repositories runs-on: - linux-x86_64 env: USE_S3_CACHE: 'true' needs: - prepare-workflow - backup - download-onedir-artifact environment: release steps: - name: Clone The Salt Repository uses: actions/checkout@v4 - name: Get Salt Project GitHub Actions Bot Environment run: | TOKEN=$(curl -sS -f -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 30") SPB_ENVIRONMENT=$(curl -sS -f -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/tags/instance/spb:environment) echo "SPB_ENVIRONMENT=$SPB_ENVIRONMENT" >> "$GITHUB_ENV" - name: Setup Python Tools Scripts uses: ./.github/actions/setup-python-tools-scripts with: cache-prefix: ${{ needs.prepare-workflow.outputs.cache-seed }} - name: Publish Release Repository env: SALT_REPO_DOMAIN_RELEASE: ${{ vars.SALT_REPO_DOMAIN_RELEASE || 'repo.saltproject.io' }} SALT_REPO_DOMAIN_STAGING: ${{ vars.SALT_REPO_DOMAIN_STAGING || 'staging.repo.saltproject.io' }} run: | tools pkg repo publish release ${{ needs.prepare-workflow.outputs.salt-version }} release: name: Release v${{ needs.prepare-workflow.outputs.salt-version }} if: ${{ always() && ! failure() && ! cancelled() }} runs-on: - linux-x86_64 env: USE_S3_CACHE: 'true' needs: - prepare-workflow - backup - publish-repositories environment: release steps: - name: Clone The Salt Repository uses: actions/checkout@v4 with: ssh-key: ${{ secrets.GHA_SSH_KEY }} - name: Setup Python Tools Scripts uses: ./.github/actions/setup-python-tools-scripts with: cache-prefix: ${{ needs.prepare-workflow.outputs.cache-seed }} - name: Setup GnuPG run: | sudo install -d -m 0700 -o "$(id -u)" -g "$(id -g)" /run/gpg GNUPGHOME="$(mktemp -d -p /run/gpg)" echo "GNUPGHOME=${GNUPGHOME}" >> "$GITHUB_ENV" cat < "${GNUPGHOME}/gpg.conf" batch no-tty pinentry-mode loopback EOF - name: Get Secrets id: get-secrets env: SECRETS_KEY: ${{ secrets.SECRETS_KEY }} run: | SECRETS_KEY_FILE=$(mktemp /tmp/output.XXXXXXXXXX) echo "$SECRETS_KEY" > "$SECRETS_KEY_FILE" aws --region us-west-2 secretsmanager get-secret-value --secret-id /cmbu-saltstack/signing/repo-signing-keys-sha256-2023 \ --query SecretString --output text | jq .default_key -r | base64 -d \ | gpg --passphrase-file "${SECRETS_KEY_FILE}" -d - \ | gpg --import - sync aws --region us-west-2 secretsmanager get-secret-value --secret-id /cmbu-saltstack/signing/repo-signing-keys-sha256-2023 \ --query SecretString --output text| jq .default_passphrase -r | base64 -d \ | gpg --passphrase-file "${SECRETS_KEY_FILE}" -o "${GNUPGHOME}/passphrase" -d - sync rm "$SECRETS_KEY_FILE" echo "passphrase-file ${GNUPGHOME}/passphrase" >> "${GNUPGHOME}/gpg.conf" - name: Prepare Release id: prepare-release run: | tools pkg repo publish github --repository ${{ github.repository }} --key-id=64CBBC8173D76B3F ${{ needs.prepare-workflow.outputs.salt-version }} - name: Configure Git shell: bash run: | git config --global --add safe.directory "$(pwd)" git config --global user.name "Salt Project Packaging" git config --global user.email saltproject-packaging@vmware.com git config --global user.signingkey 64CBBC8173D76B3F git config --global commit.gpgsign true - name: Apply The Release Patch run: | git am --committer-date-is-author-date release-artifacts/salt-${{ needs.prepare-workflow.outputs.salt-version }}.patch rm release-artifacts/salt-${{ needs.prepare-workflow.outputs.salt-version }}.patch - name: Tag The v${{ needs.prepare-workflow.outputs.salt-version }} Release run: | git tag -m "Release v${{ needs.prepare-workflow.outputs.salt-version }}" -as v${{ needs.prepare-workflow.outputs.salt-version }} - name: Push Changes uses: ad-m/github-push-action@b87afee92c6e70ea888be6203a3e9426fda49839 with: ssh: true tags: true atomic: true branch: ${{ github.ref }} - name: Create Github Release uses: ncipollo/release-action@v1 with: artifactErrorsFailBuild: true artifacts: ${{ steps.prepare-release.outputs.release-artifacts }} bodyFile: ${{ steps.prepare-release.outputs.release-messsage-file }} draft: false generateReleaseNotes: false makeLatest: fromJSON(${{ steps.prepare-release.outputs.make-latest }}) name: v${{ needs.prepare-workflow.outputs.salt-version }} prerelease: ${{ contains(needs.prepare-workflow.outputs.salt-version, 'rc') }} removeArtifacts: true replacesArtifacts: true tag: v${{ needs.prepare-workflow.outputs.salt-version }} - name: Upload PyPi Artifacts uses: actions/upload-artifact@v4 with: name: pypi-artifacts path: | release-artifacts/salt-${{ needs.prepare-workflow.outputs.salt-version }}.tar.gz release-artifacts/salt-${{ needs.prepare-workflow.outputs.salt-version }}.tar.gz.asc retention-days: 7 if-no-files-found: error publish-pypi: name: Publish to PyPi if: ${{ always() && ! failure() && ! cancelled() && github.event.repository.fork != true }} needs: - prepare-workflow - release environment: release runs-on: - linux-x86_64 env: USE_S3_CACHE: 'true' steps: - uses: actions/checkout@v4 - name: Setup Python Tools Scripts uses: ./.github/actions/setup-python-tools-scripts with: cache-prefix: ${{ needs.prepare-workflow.outputs.cache-seed }} - name: Setup GnuPG run: | sudo install -d -m 0700 -o "$(id -u)" -g "$(id -g)" /run/gpg GNUPGHOME="$(mktemp -d -p /run/gpg)" echo "GNUPGHOME=${GNUPGHOME}" >> "$GITHUB_ENV" cat < "${GNUPGHOME}/gpg.conf" batch no-tty pinentry-mode loopback EOF - name: Get Secrets id: get-secrets env: SECRETS_KEY: ${{ secrets.SECRETS_KEY }} run: | SECRETS_KEY_FILE=$(mktemp /tmp/output.XXXXXXXXXX) echo "$SECRETS_KEY" > "$SECRETS_KEY_FILE" TWINE_PASSWORD=$(aws --region us-west-2 secretsmanager get-secret-value --secret-id /cmbu-saltstack/publishing/publish-pypi \ --query SecretString --output text | jq .default_passphrase -r | base64 -d \ | gpg --passphrase-file "$SECRETS_KEY_FILE" -d -) echo "::add-mask::$TWINE_PASSWORD" echo "twine-password=$TWINE_PASSWORD" >> "${GITHUB_OUTPUT}" - name: Download PyPi Artifacts uses: actions/download-artifact@v4 with: name: pypi-artifacts path: artifacts/release - name: Publish to PyPi env: TWINE_PASSWORD: "${{ steps.get-secrets.outputs.twine-password }}" run: | tools pkg pypi-upload artifacts/release/salt-${{ needs.prepare-workflow.outputs.salt-version }}.tar.gz set-pipeline-exit-status: # This step is just so we can make github require this step, to pass checks # on a pull request instead of requiring all name: Set the ${{ github.workflow }} Pipeline Exit Status if: always() runs-on: ubuntu-22.04 needs: - check-requirements - prepare-workflow - publish-repositories - release - publish-pypi - build-ci-deps steps: - name: Get workflow information id: get-workflow-info uses: im-open/workflow-conclusion@v2 - run: | # shellcheck disable=SC2129 if [ "${{ steps.get-workflow-info.outputs.conclusion }}" != "success" ]; then echo 'To restore the release bucket run:' >> "${GITHUB_STEP_SUMMARY}" echo '```' >> "${GITHUB_STEP_SUMMARY}" echo 'tools pkg repo restore-previous-releases' >> "${GITHUB_STEP_SUMMARY}" echo '```' >> "${GITHUB_STEP_SUMMARY}" fi - name: Set Pipeline Exit Status shell: bash run: | if [ "${{ steps.get-workflow-info.outputs.workflow_conclusion }}" != "success" ]; then exit 1 else exit 0 fi