← Files DatadogARCHIVED FILE

.github/workflows/release.yaml

3.82 KB · Nov 15, 2026 · 07:40 UTC

↓ Download file

name: Release

on:
  push:
    branches:
      # Stable releases land on main; preview releases land on
      # preview-<slug> branches. Both fire this workflow to create the
      # matching GitHub Release.
      - main
      - 'preview-*'
    paths:
      - '*-plugin/plugin.json'
      - 'plugin.json'
      - 'package.json'

permissions:
  contents: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

      - name: Extract version
        id: version
        run: |
          MANIFEST=$(find . -maxdepth 2 -name plugin.json -path '*/.*-plugin/*' | head -1)
          if [ -n "$MANIFEST" ]; then
            VERSION=$(node -e "console.log(JSON.parse(require('fs').readFileSync('${MANIFEST}','utf8')).version)")
          elif [ -f plugin.json ]; then
            VERSION=$(node -e "console.log(JSON.parse(require('fs').readFileSync('plugin.json','utf8')).version)")
          elif [ -f package.json ]; then
            VERSION=$(node -e "console.log(JSON.parse(require('fs').readFileSync('package.json','utf8')).version)")
          else
            echo "No plugin.json or package.json found"
            exit 1
          fi
          # Preview versions carry a -preview.<slug> semver prerelease
          # suffix; flag those so the GitHub Release is marked accordingly.
          if [[ "${VERSION}" == *-preview.* ]]; then
            IS_PRERELEASE=true
          else
            IS_PRERELEASE=false
          fi
          echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
          echo "tag=v${VERSION}" >> "$GITHUB_OUTPUT"
          echo "is_prerelease=${IS_PRERELEASE}" >> "$GITHUB_OUTPUT"
          echo "Detected version: ${VERSION} (prerelease=${IS_PRERELEASE})"

      - name: Check if release already exists
        id: check
        run: |
          # The default shell is `bash -e` without pipefail; without this, a
          # failed lookup would be masked by wc/tr and read as "no release".
          set -o pipefail
          TAG="${{ steps.version.outputs.tag }}"
          # Match on tag_name explicitly (not `gh release view`) so this also
          # catches draft releases, which have a tag_name but no git tag ref
          # yet — otherwise every push before the draft is published would
          # create a duplicate draft for the same version.
          # With --paginate, --jq runs once per page, so emit one line per
          # matching release and count lines across all pages (gh rejects
          # --slurp together with --jq).
          MATCH=$(gh api "repos/${{ github.repository }}/releases?per_page=100" --paginate \
            --jq '.[] | select(.tag_name == env.TAG) | .tag_name' | wc -l | tr -d ' ')
          if [ "$MATCH" -gt 0 ]; then
            echo "exists=true" >> "$GITHUB_OUTPUT"
            echo "Release ${TAG} already exists (or is already drafted), skipping"
          else
            echo "exists=false" >> "$GITHUB_OUTPUT"
          fi
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          TAG: ${{ steps.version.outputs.tag }}

      - name: Create draft release
        if: steps.check.outputs.exists == 'false'
        run: |
          # Org policy blocks Actions from creating/pushing tags directly, so
          # we create a draft release instead. GitHub doesn't create the git
          # tag ref until a human publishes the draft, which is done under
          # their own (bypass-exempt) identity rather than github-actions[bot].
          TAG="${{ steps.version.outputs.tag }}"
          ARGS="--title ${TAG} --generate-notes --draft --target ${{ github.sha }}"
          if [ "${{ steps.version.outputs.is_prerelease }}" = "true" ]; then
            ARGS="$ARGS --prerelease"
          fi
          gh release create "${TAG}" $ARGS
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

SHA-256: 17afe1b3595b1e3000f780aabe81993cac9be2df762acac4f5dea748fc27524a