|  | 
| 1 |  | - | 
| 2 | 1 | name: Generate Release | 
| 3 | 2 | 
 | 
| 4 | 3 | on: | 
| 5 | 4 |   workflow_dispatch: | 
|  | 5 | +    inputs: | 
|  | 6 | +      operator_version: | 
|  | 7 | +        description: 'Operator version to release (e.g., "0.2.1")' | 
|  | 8 | +        required: true | 
|  | 9 | +        type: string | 
|  | 10 | +      llamastack_version: | 
|  | 11 | +        description: 'LlamaStack distribution version (e.g., "0.2.12")' | 
|  | 12 | +        required: true | 
|  | 13 | +        type: string | 
|  | 14 | + | 
|  | 15 | +permissions: | 
|  | 16 | +  contents: write | 
|  | 17 | +  actions: write | 
|  | 18 | + | 
|  | 19 | +env: | 
|  | 20 | +  GIT_USER_NAME: github-actions[bot] | 
|  | 21 | +  GIT_USER_EMAIL: github-actions[bot]@users.noreply.github.com | 
|  | 22 | +  GO_VERSION: '1.23' | 
| 6 | 23 | 
 | 
| 7 | 24 | jobs: | 
| 8 |  | -  placeholder: | 
| 9 |  | -    runs-on: ubuntu-latest | 
|  | 25 | +  generate-release: | 
|  | 26 | +    runs-on: ubuntu-24.04 | 
|  | 27 | +    outputs: | 
|  | 28 | +      operator_version: ${{ steps.validate.outputs.operator_version }} | 
|  | 29 | +      llamastack_version: ${{ steps.validate.outputs.llamastack_version }} | 
|  | 30 | +      release_branch: ${{ steps.validate.outputs.release_branch }} | 
|  | 31 | +    steps: | 
|  | 32 | +      - name: Checkout code | 
|  | 33 | +        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 | 
|  | 34 | +        with: | 
|  | 35 | +          fetch-depth: 0  # Need full history to check existing tags | 
|  | 36 | + | 
|  | 37 | +      - name: Validate inputs | 
|  | 38 | +        id: validate | 
|  | 39 | +        shell: bash | 
|  | 40 | +        run: | | 
|  | 41 | +          # Validate version formats and check for existing releases | 
|  | 42 | +          [[ "${{ github.event.inputs.operator_version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || { echo "Error: Invalid operator version format"; exit 1; } | 
|  | 43 | +          [[ "${{ github.event.inputs.llamastack_version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || { echo "Error: Invalid llamastack version format"; exit 1; } | 
|  | 44 | +
 | 
|  | 45 | +          # Check for existing tag idempotently | 
|  | 46 | +          if git tag -l | grep -q "^v${{ github.event.inputs.operator_version }}$"; then | 
|  | 47 | +            echo "Tag v${{ github.event.inputs.operator_version }} already exists - verifying consistency..." | 
|  | 48 | +
 | 
|  | 49 | +            # Get the commit SHA that the existing tag points to | 
|  | 50 | +            tag_sha=$(git rev-list -n 1 "v${{ github.event.inputs.operator_version }}") | 
|  | 51 | +            current_sha=$(git rev-parse HEAD) | 
|  | 52 | +
 | 
|  | 53 | +            if [ "$tag_sha" != "$current_sha" ]; then | 
|  | 54 | +              echo "Error: Tag v${{ github.event.inputs.operator_version }} exists but points to different commit ($tag_sha vs $current_sha)" | 
|  | 55 | +              exit 1 | 
|  | 56 | +            fi | 
|  | 57 | +
 | 
|  | 58 | +            echo "✅ Tag v${{ github.event.inputs.operator_version }} already exists and points to current commit - release is idempotent" | 
|  | 59 | +          else | 
|  | 60 | +            echo "✅ Tag v${{ github.event.inputs.operator_version }} does not exist - proceeding with new release" | 
|  | 61 | +          fi | 
|  | 62 | +
 | 
|  | 63 | +          # Extract major.minor for branch name (e.g., "0.2.1" -> "0.2") | 
|  | 64 | +          major_minor=$(echo "${{ github.event.inputs.operator_version }}" | cut -d. -f1-2) | 
|  | 65 | +
 | 
|  | 66 | +          # Set outputs for later steps | 
|  | 67 | +          echo "operator_version=${{ github.event.inputs.operator_version }}" >> $GITHUB_OUTPUT | 
|  | 68 | +          echo "llamastack_version=${{ github.event.inputs.llamastack_version }}" >> $GITHUB_OUTPUT | 
|  | 69 | +          echo "release_branch=release-$major_minor" >> $GITHUB_OUTPUT | 
|  | 70 | +
 | 
|  | 71 | +      - name: Configure git | 
|  | 72 | +        shell: bash | 
|  | 73 | +        run: | | 
|  | 74 | +          git config user.name "${{ env.GIT_USER_NAME }}" | 
|  | 75 | +          git config user.email "${{ env.GIT_USER_EMAIL }}" | 
|  | 76 | +
 | 
|  | 77 | +      - name: Create or checkout release branch | 
|  | 78 | +        shell: bash | 
|  | 79 | +        run: | | 
|  | 80 | +          release_branch="${{ steps.validate.outputs.release_branch }}" | 
|  | 81 | +
 | 
|  | 82 | +          # Check if release branch exists remotely | 
|  | 83 | +          if git ls-remote --heads origin | grep -q "refs/heads/$release_branch"; then | 
|  | 84 | +            echo "Checking out existing release branch: $release_branch" | 
|  | 85 | +            git fetch origin "$release_branch" | 
|  | 86 | +            git checkout "$release_branch" | 
|  | 87 | +            git pull origin "$release_branch" | 
|  | 88 | +          else | 
|  | 89 | +            echo "Creating new release branch: $release_branch" | 
|  | 90 | +            git checkout -b "$release_branch" | 
|  | 91 | +          fi | 
|  | 92 | +
 | 
|  | 93 | +      - name: Set up Go | 
|  | 94 | +        uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 | 
|  | 95 | +        with: | 
|  | 96 | +          go-version: ${{ env.GO_VERSION }} | 
|  | 97 | + | 
|  | 98 | +      - name: Prepare release files | 
|  | 99 | +        shell: bash | 
|  | 100 | +        run: | | 
|  | 101 | +          # Use the make release command to update all necessary files | 
|  | 102 | +          make release VERSION=${{ steps.validate.outputs.operator_version }} LLAMASTACK_VERSION=${{ steps.validate.outputs.llamastack_version }} | 
|  | 103 | +
 | 
|  | 104 | +      - name: Set up Python | 
|  | 105 | +        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 | 
|  | 106 | +        with: | 
|  | 107 | +          python-version: '3.12' | 
|  | 108 | + | 
|  | 109 | +      - name: Run pre-commit checks | 
|  | 110 | +        uses: pre-commit/action@a26af69be951a213d495a4c3e4e4022e16d87065 | 
|  | 111 | +        continue-on-error: true | 
|  | 112 | +        id: precommit | 
|  | 113 | +        env: | 
|  | 114 | +          IMG: quay.io/llamastack/llama-stack-k8s-operator:v${{ steps.validate.outputs.operator_version }} | 
|  | 115 | + | 
|  | 116 | +      - name: Handle pre-commit changes | 
|  | 117 | +        shell: bash | 
|  | 118 | +        env: | 
|  | 119 | +          IMG: quay.io/llamastack/llama-stack-k8s-operator:v${{ steps.validate.outputs.operator_version }} | 
|  | 120 | +        run: | | 
|  | 121 | +          # Check if there are any modified files after pre-commit | 
|  | 122 | +          if [ "${{ steps.precommit.outcome }}" = "failure" ]; then | 
|  | 123 | +            echo "📝 Pre-commit checks failed - checking for file modifications" | 
|  | 124 | +
 | 
|  | 125 | +            # Show what files exist and their status | 
|  | 126 | +            echo "Git status before staging:" | 
|  | 127 | +            git status --porcelain | 
|  | 128 | +
 | 
|  | 129 | +            git add . | 
|  | 130 | +
 | 
|  | 131 | +            echo "Git status after staging:" | 
|  | 132 | +            git status --porcelain | 
|  | 133 | +
 | 
|  | 134 | +            # Check if there are staged changes | 
|  | 135 | +            if git diff --staged --quiet; then | 
|  | 136 | +              echo "⚠️  No staged changes detected, but pre-commit failed" | 
|  | 137 | +              echo "This suggests pre-commit failed due to issues that weren't auto-fixable" | 
|  | 138 | +              echo "❌ Pre-commit checks failed without auto-fixes" | 
|  | 139 | +              exit 1 | 
|  | 140 | +            else | 
|  | 141 | +              echo "📝 Staged changes detected - committing them" | 
|  | 142 | +              git commit -s -m "Apply pre-commit fixes for release ${{ steps.validate.outputs.operator_version }}" \ | 
|  | 143 | +                           -m "- Auto-format and regenerate release manifests" \ | 
|  | 144 | +                           -m "- Ensure consistency after release preparation" | 
|  | 145 | +              git push origin "${{ steps.validate.outputs.release_branch }}" | 
|  | 146 | +
 | 
|  | 147 | +              # Re-run pre-commit to ensure all checks pass | 
|  | 148 | +              echo "🔄 Re-running pre-commit to verify all checks pass" | 
|  | 149 | +              pre-commit run --show-diff-on-failure --color=always --all-files | 
|  | 150 | +              echo "✅ Pre-commit checks passed after applying fixes" | 
|  | 151 | +            fi | 
|  | 152 | +          else | 
|  | 153 | +            echo "✅ Pre-commit checks passed" | 
|  | 154 | +          fi | 
|  | 155 | +
 | 
|  | 156 | +      - name: Run unit and integration tests | 
|  | 157 | +        shell: bash | 
|  | 158 | +        run: | | 
|  | 159 | +          make test | 
|  | 160 | +
 | 
|  | 161 | +      - name: Validate build release image | 
|  | 162 | +        shell: bash | 
|  | 163 | +        run: | | 
|  | 164 | +          make image-build IMG=quay.io/llamastack/llama-stack-k8s-operator:v${{ steps.validate.outputs.operator_version }} | 
|  | 165 | +
 | 
|  | 166 | +      - name: Commit and push changes | 
|  | 167 | +        shell: bash | 
|  | 168 | +        run: | | 
|  | 169 | +          git add . | 
|  | 170 | +          if git diff --staged --quiet; then | 
|  | 171 | +            echo "No changes to commit - release files are already up to date" | 
|  | 172 | +          else | 
|  | 173 | +            git commit -s -m "v${{ steps.validate.outputs.operator_version }}" \ | 
|  | 174 | +                         -m "- Update operator version to v${{ steps.validate.outputs.operator_version }}" \ | 
|  | 175 | +                         -m "- Update LlamaStack distributions to ${{ steps.validate.outputs.llamastack_version }}" \ | 
|  | 176 | +                         -m "- Generate release manifests" | 
|  | 177 | +            git push origin "${{ steps.validate.outputs.release_branch }}" | 
|  | 178 | +            echo "✅ Committed release changes to ${{ steps.validate.outputs.release_branch }}" | 
|  | 179 | +          fi | 
|  | 180 | +
 | 
|  | 181 | +  finalize-release: | 
|  | 182 | +    needs: generate-release | 
|  | 183 | +    runs-on: ubuntu-24.04 | 
|  | 184 | +    env: | 
|  | 185 | +      operator_version: ${{ needs.generate-release.outputs.operator_version }} | 
|  | 186 | +      llamastack_version: ${{ needs.generate-release.outputs.llamastack_version }} | 
|  | 187 | +      release_branch: ${{ needs.generate-release.outputs.release_branch }} | 
| 10 | 188 |     steps: | 
| 11 |  | -      - run: echo "This is a placeholder job to make the workflow discoverable by the GitHub API." | 
|  | 189 | +      - name: Checkout code | 
|  | 190 | +        uses: actions/checkout@a26af69be951a213d495a4c3e4e4022e16d87065 | 
|  | 191 | +        with: | 
|  | 192 | +          ref: ${{ env.release_branch }} | 
|  | 193 | +          fetch-depth: 0 | 
|  | 194 | + | 
|  | 195 | +      - name: Configure git | 
|  | 196 | +        shell: bash | 
|  | 197 | +        run: | | 
|  | 198 | +          git config user.name "${{ env.GIT_USER_NAME }}" | 
|  | 199 | +          git config user.email "${{ env.GIT_USER_EMAIL }}" | 
|  | 200 | +
 | 
|  | 201 | +      - name: Create and push the release tag | 
|  | 202 | +        shell: bash | 
|  | 203 | +        run: | | 
|  | 204 | +          if git tag -l | grep -q "^v${{ env.operator_version }}$"; then | 
|  | 205 | +            echo "✅ Tag v${{ env.operator_version }} already exists - skipping creation" | 
|  | 206 | +          else | 
|  | 207 | +            git tag -a "v${{ env.operator_version }}" -m "Release v${{ env.operator_version }}" | 
|  | 208 | +            git push origin "v${{ env.operator_version }}" | 
|  | 209 | +            echo "✅ Created tag v${{ env.operator_version }}" | 
|  | 210 | +          fi | 
|  | 211 | +
 | 
|  | 212 | +      - name: Create GitHub Release | 
|  | 213 | +        shell: bash | 
|  | 214 | +        run: | | 
|  | 215 | +          if gh release view "v${{ env.operator_version }}" >/dev/null 2>&1; then | 
|  | 216 | +            echo "✅ GitHub release v${{ env.operator_version }} already exists - skipping creation" | 
|  | 217 | +          else | 
|  | 218 | +            RELEASE_NOTES="## What's Changed | 
|  | 219 | +
 | 
|  | 220 | +            - Updated operator version to v${{ env.operator_version }} | 
|  | 221 | +            - Updated LlamaStack distributions to ${{ env.llamastack_version }} | 
|  | 222 | +            - Generated updated release manifests | 
|  | 223 | +
 | 
|  | 224 | +            ## Installation | 
|  | 225 | +
 | 
|  | 226 | +            Install the operator using kubectl: | 
|  | 227 | +
 | 
|  | 228 | +            \`\`\`bash | 
|  | 229 | +            kubectl apply -f https://raw.githubusercontent.com/llamastack/llama-stack-k8s-operator/v${{ env.operator_version }}/release/operator.yaml | 
|  | 230 | +            \`\`\` | 
|  | 231 | +
 | 
|  | 232 | +            ## Container Images | 
|  | 233 | +
 | 
|  | 234 | +            - Operator: \`quay.io/llamastack/llama-stack-k8s-operator:v${{ env.operator_version }}\` | 
|  | 235 | +            - LlamaStack distributions: \`docker.io/llamastack/distribution-*:${{ env.llamastack_version }}\`" | 
|  | 236 | +
 | 
|  | 237 | +            gh release create "v${{ env.operator_version }}" \ | 
|  | 238 | +              --title "v${{ env.operator_version }}" \ | 
|  | 239 | +              --notes "$RELEASE_NOTES" | 
|  | 240 | +
 | 
|  | 241 | +            echo "🎉 Created GitHub release v${{ env.operator_version }}" | 
|  | 242 | +          fi | 
|  | 243 | +        env: | 
|  | 244 | +          GH_TOKEN: ${{ github.token }} | 
|  | 245 | + | 
|  | 246 | +      - name: Set up Go | 
|  | 247 | +        uses: actions/setup-go@a26af69be951a213d495a4c3e4e4022e16d87065 | 
|  | 248 | +        with: | 
|  | 249 | +          go-version: ${{ env.GO_VERSION }} | 
|  | 250 | + | 
|  | 251 | +      - name: Build release image | 
|  | 252 | +        shell: bash | 
|  | 253 | +        run: | | 
|  | 254 | +          make image-build IMG=quay.io/llamastack/llama-stack-k8s-operator:v${{ env.operator_version }} | 
|  | 255 | +
 | 
|  | 256 | +      - name: Log in to Quay.io | 
|  | 257 | +        uses: docker/login-action@a26af69be951a213d495a4c3e4e4022e16d87065 | 
|  | 258 | +        with: | 
|  | 259 | +          registry: quay.io | 
|  | 260 | +          username: ${{ secrets.APP_QUAY_USERNAME }} | 
|  | 261 | +          password: ${{ secrets.APP_QUAY_TOKEN }} | 
|  | 262 | + | 
|  | 263 | +      - name: Push release image | 
|  | 264 | +        shell: bash | 
|  | 265 | +        run: | | 
|  | 266 | +          make image-push IMG=quay.io/llamastack/llama-stack-k8s-operator:v${{ env.operator_version }} | 
|  | 267 | +          echo "✅ Pushed: quay.io/llamastack/llama-stack-k8s-operator:v${{ env.operator_version }}" | 
|  | 268 | +
 | 
|  | 269 | +      - name: Release complete | 
|  | 270 | +        shell: bash | 
|  | 271 | +        run: | | 
|  | 272 | +          echo "🚀 Release v${{ env.operator_version }} completed successfully!" | 
|  | 273 | +          echo "📦 Container image: quay.io/llamastack/llama-stack-k8s-operator:v${{ env.operator_version }}" | 
|  | 274 | +          echo "📝 Release notes: https://github.com/${{ github.repository }}/releases/tag/v${{ env.operator_version }}" | 
|  | 275 | +          echo "🔧 Install with: kubectl apply -f https://raw.githubusercontent.com/llamastack/llama-stack-k8s-operator/v${{ env.operator_version }}/release/operator.yaml" | 
|  | 276 | +          echo "🌿 Release branch: ${{ env.release_branch }}" | 
0 commit comments