diff --git a/.github/actions/update-floating-tags/action.yml b/.github/actions/update-floating-tags/action.yml new file mode 100644 index 000000000..21ad9229d --- /dev/null +++ b/.github/actions/update-floating-tags/action.yml @@ -0,0 +1,81 @@ +name: 'Update floating tags' +description: 'Push floating major/minor/latest git tags and recreate corresponding GitHub releases' + +inputs: + release-version: + description: 'Release version without v prefix (e.g. 1.2.3)' + required: true + tag-prefix: + description: 'Git tag prefix (e.g. "gitlab/", "github/", "rules/", or empty for CLI)' + required: true + default: '' + component-name: + description: 'Human-readable component name for release notes (e.g. "GitLab CI template")' + required: true + release-assets: + description: 'Files to attach to floating releases (space-separated paths)' + required: false + default: '' + copy-assets-from: + description: 'Tag to copy assets from (e.g. v0.1.2). Mutually exclusive with release-assets.' + required: false + default: '' + +runs: + using: 'composite' + steps: + - name: Update floating tags + shell: bash + run: | + set -euo pipefail + + VERSION="$(echo "${{ inputs.release-version }}" | sed 's/^v//')" + PREFIX="${{ inputs.tag-prefix }}" + COMPONENT="${{ inputs.component-name }}" + MAJOR="$(echo "$VERSION" | cut -d. -f1)" + MAJOR_TAG="${PREFIX}v${MAJOR}" + MINOR_TAG="${PREFIX}v$(echo "$VERSION" | cut -d. -f1-2)" + LATEST_TAG="${PREFIX}latest" + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + git tag -f "$MAJOR_TAG" + git push origin "$MAJOR_TAG" --force + git tag -f "$MINOR_TAG" + git push origin "$MINOR_TAG" --force + git tag -f "$LATEST_TAG" + git push origin "$LATEST_TAG" --force + + ASSET_ARGS=() + ASSETS_DIR="" + if [ -n "${{ inputs.copy-assets-from }}" ]; then + ASSETS_DIR=$(mktemp -d) + gh release download "${{ inputs.copy-assets-from }}" --dir "$ASSETS_DIR" + for f in "$ASSETS_DIR"/*; do + [ -f "$f" ] || continue + ASSET_ARGS+=("$f") + done + elif [ -n "${{ inputs.release-assets }}" ]; then + read -ra ASSET_ARGS <<< "${{ inputs.release-assets }}" + fi + + gh release delete "$LATEST_TAG" --yes || true + gh release create "$LATEST_TAG" \ + --title "$LATEST_TAG" \ + --notes "Floating release tracking the latest ${COMPONENT} version (${PREFIX}v${VERSION})" \ + --latest=false \ + --prerelease \ + "${ASSET_ARGS[@]+"${ASSET_ARGS[@]}"}" + + gh release delete "$MINOR_TAG" --yes || true + gh release create "$MINOR_TAG" \ + --title "$MINOR_TAG" \ + --notes "Floating release tracking the latest ${COMPONENT} ${MINOR_TAG#${PREFIX}}.x version (${PREFIX}v${VERSION})" \ + --latest=false \ + --prerelease \ + "${ASSET_ARGS[@]+"${ASSET_ARGS[@]}"}" + + if [ -n "$ASSETS_DIR" ]; then + rm -rf "$ASSETS_DIR" + fi diff --git a/.github/workflows/release-cli.yaml b/.github/workflows/release-cli.yaml index 2a06ea598..628ebfbe7 100644 --- a/.github/workflows/release-cli.yaml +++ b/.github/workflows/release-cli.yaml @@ -16,7 +16,7 @@ on: concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: release-${{ github.ref }} cancel-in-progress: false env: @@ -73,6 +73,9 @@ jobs: git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git tag "v${{ steps.manual_release.outputs.new-version }}" git push origin "v${{ steps.manual_release.outputs.new-version }}" + - + name: Force-update tags + run: git fetch --tags --force - name: 'Release (auto)' if: ${{ github.event_name != 'workflow_dispatch' || github.event.inputs.release_type == 'auto' }} @@ -275,60 +278,16 @@ jobs: OPENTAINT_OWNER=${{ github.repository_owner }} SEQRA_BUILD_FLAGS=-s -w -X github.com/${{ github.repository_owner }}/opentaint/internal/version.Version=${{ steps.release_version.outputs.RELEASE_VERSION }} - - name: Update floating latest tag - if: ${{ steps.release_version.outputs.status == 'succeeded' }} - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - RELEASE_TAG="v${{ steps.release_version.outputs.RELEASE_VERSION }}" - - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git tag -f "latest" - git push origin "latest" --force - - gh release delete "latest" --yes || true - gh release create "latest" \ - --title "latest" \ - --notes "Floating release tracking the latest CLI version (${RELEASE_TAG})" \ - --latest=false \ - --prerelease - - ASSETS_DIR=$(mktemp -d) - gh release download "$RELEASE_TAG" --dir "$ASSETS_DIR" - for f in "$ASSETS_DIR"/*; do - [ -f "$f" ] || continue - gh release upload "latest" "$f" --clobber - done - rm -rf "$ASSETS_DIR" - - - name: Update floating minor version tag + name: Update floating version tags if: ${{ steps.release_version.outputs.status == 'succeeded' }} + uses: ./.github/actions/update-floating-tags env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - RELEASE_TAG="v${{ steps.release_version.outputs.RELEASE_VERSION }}" - MINOR_TAG="v$(echo "${{ steps.release_version.outputs.RELEASE_VERSION }}" | cut -d. -f1-2)" - - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git tag -f "$MINOR_TAG" - git push origin "$MINOR_TAG" --force - - gh release delete "$MINOR_TAG" --yes || true - gh release create "$MINOR_TAG" \ - --title "$MINOR_TAG" \ - --notes "Floating release tracking the latest CLI ${MINOR_TAG}.x version (${RELEASE_TAG})" \ - --latest=false \ - --prerelease - - ASSETS_DIR=$(mktemp -d) - gh release download "$RELEASE_TAG" --dir "$ASSETS_DIR" - for f in "$ASSETS_DIR"/*; do - [ -f "$f" ] || continue - gh release upload "$MINOR_TAG" "$f" --clobber - done - rm -rf "$ASSETS_DIR" + with: + release-version: ${{ steps.release_version.outputs.RELEASE_VERSION }} + tag-prefix: '' + component-name: 'CLI' + copy-assets-from: v${{ steps.release_version.outputs.RELEASE_VERSION }} outputs: release_version: ${{ steps.release_version.outputs.RELEASE_VERSION }} diff --git a/.github/workflows/release-github.yaml b/.github/workflows/release-github.yaml index 2bd44e470..951450159 100644 --- a/.github/workflows/release-github.yaml +++ b/.github/workflows/release-github.yaml @@ -16,7 +16,7 @@ on: concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: release-${{ github.ref }} cancel-in-progress: false permissions: @@ -78,6 +78,9 @@ jobs: --generate-notes \ --latest=false + - name: Force-update tags + run: git fetch --tags --force + - name: Release (auto) if: ${{ github.event_name != 'workflow_dispatch' || github.event.inputs.release_type == 'auto' }} uses: cycjimmy/semantic-release-action@v4 @@ -92,46 +95,27 @@ jobs: @semantic-release/exec@6.0.3 conventional-changelog-conventionalcommits@7.0.2 - - name: Unmark release as latest + - name: Publish release as non-latest if: ${{ steps.manual_release.outputs.new-version != '' || steps.version.outputs.new_release_published == 'true' }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | RELEASE_VERSION="${{ steps.manual_release.outputs.new-version || steps.version.outputs.new_release_version }}" RELEASE_TAG="github/v$(echo "$RELEASE_VERSION" | sed 's/^v//')" - gh release edit "$RELEASE_TAG" --latest=false + RELEASE_ID=$(gh api "repos/$GITHUB_REPOSITORY/releases/tags/$RELEASE_TAG" -q '.id') + gh api -X PATCH "repos/$GITHUB_REPOSITORY/releases/$RELEASE_ID" \ + -F draft=false \ + -f make_latest=false - - name: Push floating version tags + - name: Update floating version tags if: ${{ steps.manual_release.outputs.new-version != '' || steps.version.outputs.new_release_published == 'true' }} + uses: ./.github/actions/update-floating-tags env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - RELEASE_VERSION="${{ steps.manual_release.outputs.new-version || steps.version.outputs.new_release_version }}" - MAJOR="${{ steps.manual_release.outputs.major-version || steps.version.outputs.new_release_major_version }}" - MINOR_TAG="github/v$(echo "$RELEASE_VERSION" | cut -d. -f1-2)" - - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git tag -f "github/v${MAJOR}" - git push origin "github/v${MAJOR}" --force - git tag -f "$MINOR_TAG" - git push origin "$MINOR_TAG" --force - git tag -f "github/latest" - git push origin "github/latest" --force - - gh release delete "$MINOR_TAG" --yes || true - gh release create "$MINOR_TAG" \ - --title "$MINOR_TAG" \ - --notes "Floating release tracking the latest GitHub Action ${MINOR_TAG#github/}.x version (github/v${RELEASE_VERSION})" \ - --latest=false \ - --prerelease - - gh release delete "github/latest" --yes || true - gh release create "github/latest" \ - --title "github/latest" \ - --notes "Floating release tracking the latest GitHub Action version (v${RELEASE_VERSION})" \ - --latest=false \ - --prerelease + with: + release-version: ${{ steps.manual_release.outputs.new-version || steps.version.outputs.new_release_version }} + tag-prefix: 'github/' + component-name: 'GitHub Action' outputs: release_version: ${{ steps.manual_release.outputs.new-version || steps.version.outputs.new_release_version }} diff --git a/.github/workflows/release-gitlab.yaml b/.github/workflows/release-gitlab.yaml index 28980b15e..c3da0b74c 100644 --- a/.github/workflows/release-gitlab.yaml +++ b/.github/workflows/release-gitlab.yaml @@ -16,7 +16,7 @@ on: concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: release-${{ github.ref }} cancel-in-progress: false permissions: @@ -80,6 +80,9 @@ jobs: echo "v${{ steps.manual_release.outputs.new-version }}" > gitlab/release_version.txt + - name: Force-update tags + run: git fetch --tags --force + - name: Release (auto) if: ${{ github.event_name != 'workflow_dispatch' || github.event.inputs.release_type == 'auto' }} uses: cycjimmy/semantic-release-action@v4 @@ -106,7 +109,7 @@ jobs: fi rm -f release_version.txt - - name: Unmark release as latest + - name: Publish release as non-latest if: ${{ steps.manual_release.outputs.new-version != '' || steps.release_version.outputs.status == 'succeeded' }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -116,55 +119,20 @@ jobs: RELEASE_VERSION="${{ steps.release_version.outputs.RELEASE_VERSION }}" fi RELEASE_TAG="gitlab/v$(echo "$RELEASE_VERSION" | sed 's/^v//')" - gh release edit "$RELEASE_TAG" --latest=false + RELEASE_ID=$(gh api "repos/$GITHUB_REPOSITORY/releases/tags/$RELEASE_TAG" -q '.id') + gh api -X PATCH "repos/$GITHUB_REPOSITORY/releases/$RELEASE_ID" \ + -F draft=false \ + -f make_latest=false - - name: Update floating latest tag + - name: Update floating version tags if: ${{ steps.manual_release.outputs.new-version != '' || steps.release_version.outputs.status == 'succeeded' }} + uses: ./.github/actions/update-floating-tags env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git tag -f "gitlab/latest" - git push origin "gitlab/latest" --force - - LATEST_VERSION="${{ steps.manual_release.outputs.new-version }}" - if [ -n "$LATEST_VERSION" ]; then - LATEST_VERSION="v${LATEST_VERSION}" - else - LATEST_VERSION="${{ steps.release_version.outputs.RELEASE_VERSION }}" - fi - - gh release delete "gitlab/latest" --yes || true - gh release create "gitlab/latest" \ - --title "gitlab/latest" \ - --notes "Floating release tracking the latest GitLab CI template version (${LATEST_VERSION})" \ - --latest=false \ - --prerelease - - - name: Update floating minor version tag - if: ${{ steps.manual_release.outputs.new-version != '' || steps.release_version.outputs.status == 'succeeded' }} - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - RELEASE_VERSION="${{ steps.manual_release.outputs.new-version }}" - if [ -z "$RELEASE_VERSION" ]; then - RELEASE_VERSION="${{ steps.release_version.outputs.RELEASE_VERSION }}" - fi - RELEASE_VERSION="$(echo "$RELEASE_VERSION" | sed 's/^v//')" - MINOR_TAG="gitlab/v$(echo "$RELEASE_VERSION" | cut -d. -f1-2)" - - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git tag -f "$MINOR_TAG" - git push origin "$MINOR_TAG" --force - - gh release delete "$MINOR_TAG" --yes || true - gh release create "$MINOR_TAG" \ - --title "$MINOR_TAG" \ - --notes "Floating release tracking the latest GitLab CI template ${MINOR_TAG#gitlab/}.x version (gitlab/v${RELEASE_VERSION})" \ - --latest=false \ - --prerelease + with: + release-version: ${{ steps.manual_release.outputs.new-version || steps.release_version.outputs.RELEASE_VERSION }} + tag-prefix: 'gitlab/' + component-name: 'GitLab CI template' outputs: release_version: ${{ steps.manual_release.outputs.new-version || steps.release_version.outputs.RELEASE_VERSION }} diff --git a/.github/workflows/release-rules.yaml b/.github/workflows/release-rules.yaml index 69b36e1d5..4664cbdb4 100644 --- a/.github/workflows/release-rules.yaml +++ b/.github/workflows/release-rules.yaml @@ -16,7 +16,7 @@ on: concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: release-${{ github.ref }} cancel-in-progress: false jobs: @@ -85,6 +85,9 @@ jobs: echo "v${{ steps.manual_release.outputs.new-version }}" > rules/release_version.txt + - name: Force-update tags + run: git fetch --tags --force + - name: Release (auto) if: ${{ github.event_name != 'workflow_dispatch' || github.event.inputs.release_type == 'auto' }} uses: cycjimmy/semantic-release-action@v4 @@ -111,7 +114,7 @@ jobs: fi rm -f release_version.txt - - name: Unmark release as latest + - name: Publish release as non-latest if: ${{ steps.manual_release.outputs.new-version != '' || steps.release_version.outputs.status == 'succeeded' }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -121,57 +124,21 @@ jobs: RELEASE_VERSION="${{ steps.release_version.outputs.RELEASE_VERSION }}" fi RELEASE_TAG="rules/v$(echo "$RELEASE_VERSION" | sed 's/^v//')" - gh release edit "$RELEASE_TAG" --latest=false - - - name: Update floating latest tag - if: ${{ steps.manual_release.outputs.new-version != '' || steps.release_version.outputs.status == 'succeeded' }} - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git tag -f "rules/latest" - git push origin "rules/latest" --force - - LATEST_VERSION="${{ steps.manual_release.outputs.new-version }}" - if [ -n "$LATEST_VERSION" ]; then - LATEST_VERSION="v${LATEST_VERSION}" - else - LATEST_VERSION="${{ steps.release_version.outputs.RELEASE_VERSION }}" - fi - - gh release delete "rules/latest" --yes || true - gh release create "rules/latest" \ - --title "rules/latest" \ - --notes "Floating release tracking the latest rules version (${LATEST_VERSION})" \ - --latest=false \ - --prerelease \ - opentaint-rules.tar.gz + RELEASE_ID=$(gh api "repos/$GITHUB_REPOSITORY/releases/tags/$RELEASE_TAG" -q '.id') + gh api -X PATCH "repos/$GITHUB_REPOSITORY/releases/$RELEASE_ID" \ + -F draft=false \ + -f make_latest=false - - name: Update floating minor version tag + - name: Update floating version tags if: ${{ steps.manual_release.outputs.new-version != '' || steps.release_version.outputs.status == 'succeeded' }} + uses: ./.github/actions/update-floating-tags env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - RELEASE_VERSION="${{ steps.manual_release.outputs.new-version }}" - if [ -z "$RELEASE_VERSION" ]; then - RELEASE_VERSION="${{ steps.release_version.outputs.RELEASE_VERSION }}" - fi - RELEASE_VERSION="$(echo "$RELEASE_VERSION" | sed 's/^v//')" - MINOR_TAG="rules/v$(echo "$RELEASE_VERSION" | cut -d. -f1-2)" - - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git tag -f "$MINOR_TAG" - git push origin "$MINOR_TAG" --force - - gh release delete "$MINOR_TAG" --yes || true - gh release create "$MINOR_TAG" \ - --title "$MINOR_TAG" \ - --notes "Floating release tracking the latest rules ${MINOR_TAG#rules/}.x version (rules/v${RELEASE_VERSION})" \ - --latest=false \ - --prerelease \ - opentaint-rules.tar.gz + with: + release-version: ${{ steps.manual_release.outputs.new-version || steps.release_version.outputs.RELEASE_VERSION }} + tag-prefix: 'rules/' + component-name: 'rules' + release-assets: opentaint-rules.tar.gz outputs: release_version: ${{ steps.manual_release.outputs.new-version || steps.release_version.outputs.RELEASE_VERSION }} diff --git a/github/.releaserc.cjs b/github/.releaserc.cjs index d4bcf83b0..744690472 100644 --- a/github/.releaserc.cjs +++ b/github/.releaserc.cjs @@ -44,6 +44,7 @@ module.exports = { failTitle: false, labels: false, releasedLabels: false, + draftRelease: true, assets: [], }, ], diff --git a/gitlab/.releaserc.cjs b/gitlab/.releaserc.cjs index f51d39e17..4d9070c3b 100644 --- a/gitlab/.releaserc.cjs +++ b/gitlab/.releaserc.cjs @@ -44,6 +44,7 @@ module.exports = { failTitle: false, labels: false, releasedLabels: false, + draftRelease: true, assets: [], }, ], diff --git a/rules/.releaserc.cjs b/rules/.releaserc.cjs index 0ce48e31b..17a634c44 100644 --- a/rules/.releaserc.cjs +++ b/rules/.releaserc.cjs @@ -44,6 +44,7 @@ module.exports = { failTitle: false, labels: false, releasedLabels: false, + draftRelease: true, assets: [ { path: '../opentaint-rules.tar.gz',