diff --git a/.github/workflows/.release.yml b/.github/workflows/.release.yml new file mode 100644 index 0000000..5ed963b --- /dev/null +++ b/.github/workflows/.release.yml @@ -0,0 +1,138 @@ +# This internal workflow creates a semver signed git tag. +name: .release + +# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + workflow_dispatch: + inputs: + version: + description: "Semver version (e.g. v1.2.3)" + required: true + type: string + ref: + description: "Optional Git ref to tag (defaults to main HEAD)" + required: false + type: string + default: refs/heads/main + +env: + GITSIGN_VERSION: v0.14.0 + +jobs: + prepare: + runs-on: ubuntu-latest + steps: + - + name: Show inputs + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + INPUT_VERSION: ${{ inputs.version }} + INPUT_REF: ${{ inputs.ref }} + with: + script: | + core.info(`version: ${core.getInput('version')}`); + core.info(`ref: ${core.getInput('ref')}`); + + release: + runs-on: ubuntu-latest + environment: release-prod + needs: + - prepare + permissions: + contents: write # required to push the tag + id-token: write # required for keyless gitsign + steps: + - + name: Install npm deps + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + with: + script: | + await core.group(`Install npm deps`, async () => { + await exec.exec('npm', ['install', 'semver']); + }); + - + name: Check version + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + INPUT_VERSION: ${{ inputs.version }} + with: + script: | + const semver = require('semver'); + const version = core.getInput('version'); + if (!semver.valid(version)) { + core.setFailed(`Invalid version: ${version}`); + } + - + name: GitHub auth token from GitHub App + id: write-app + uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 + with: + app-id: ${{ secrets.GITHUB_BUILDER_REPO_WRITE_APP_ID }} + private-key: ${{ secrets.GITHUB_BUILDER_REPO_WRITE_APP_PRIVATE_KEY }} + owner: docker + repositories: github-builder + - + name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ inputs.ref }} + fetch-depth: 0 + token: ${{ steps.write-app.outputs.token }} + - + name: Ensure tag does not exist + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + INPUT_VERSION: ${{ inputs.version }} + with: + script: | + const version = core.getInput('version'); + await exec.exec('git', ['rev-parse', '-q', '--verify', `refs/tags/${version}`], { + ignoreReturnCode: true + }).then(res => { + if (res.exitCode === 0) { + throw new Error(`Tag ${version} already exists at ${res.stdout.trim()}`); + } + }); + - + name: Install Gitsign + run: | + set -x + go install github.com/sigstore/gitsign@${GITSIGN_VERSION} + gitsign --version + - + name: Configure Git for Gitsign + run: | + set -x + git config user.name "${GITHUB_ACTOR}" + git config user.email "${GITHUB_ACTOR_ID}+${GITHUB_ACTOR}@users.noreply.github.com" + git config gpg.format x509 + git config gpg.x509.program gitsign + git config tag.gpgsign true + git config gitsign.connectorID https://github.com/login/oauth + git config gitsign.tokenProvider github-actions + - + name: Create signed tag + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + INPUT_VERSION: ${{ inputs.version }} + with: + script: | + const version = core.getInput('version'); + await exec.exec('git', ['tag', '-a', version, '-m', version]); + await exec.exec('git', ['tag', '-v', version]); + - + name: Push tag + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + INPUT_VERSION: ${{ inputs.version }} + with: + script: | + const version = core.getInput('version'); + await exec.exec('git', ['push', 'origin', `refs/tags/${version}`]);