Version and Release - [ main ] - minor #263
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Version and Release | |
| run-name: Version and Release - [ ${{ github.ref_name }} ] - ${{ github.event.inputs.release_type }} | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| release_type: | |
| description: 'Release type' | |
| required: true | |
| default: 'minor' | |
| type: choice | |
| options: | |
| - major | |
| - minor | |
| - patch | |
| enable_blob_upload: | |
| description: 'Upload Iframe App to Azure Blob Storage' | |
| required: false | |
| default: true | |
| type: boolean | |
| repository_dispatch: | |
| types: [release] | |
| schedule: | |
| - cron: '0 17 * * 4' | |
| env: | |
| AI_KEY: ${{ vars.AI_KEY }} | |
| NX_AI_CON_STR: InstrumentationKey=3cf0d6ae-3327-414a-b7c1-12f31ef45eff;IngestionEndpoint=https://eastus-8.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus.livediagnostics.monitor.azure.com/ | |
| jobs: | |
| validation: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: 'Check branch and release type' | |
| id: validate | |
| run: | | |
| BRANCH_NAME="${{ github.ref_name }}" | |
| RELEASE_TYPE="${{ github.event.inputs.release_type || 'minor' }}" | |
| echo "Branch: $BRANCH_NAME" | |
| echo "Release Type: $RELEASE_TYPE" | |
| if [[ "$BRANCH_NAME" == "main" && "$RELEASE_TYPE" == "patch" ]]; then | |
| echo "Patch releases are not allowed on the main branch." | |
| exit 1 | |
| fi | |
| if [[ "$BRANCH_NAME" == hotfix/* && "$RELEASE_TYPE" != "patch" ]]; then | |
| echo "Major and minor releases are only allowed on the main branch." | |
| exit 1 | |
| fi | |
| create-release: | |
| needs: validation | |
| runs-on: ubuntu-latest | |
| outputs: | |
| new_version: ${{ steps.version.outputs.new_version }} | |
| tag_name: ${{ steps.version.outputs.tag_name }} | |
| permissions: write-all | |
| steps: | |
| - name: 'Checkout Github Action' | |
| uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| fetch-depth: 0 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - uses: pnpm/action-setup@v3 | |
| with: | |
| version: 9.1.3 | |
| run_install: | | |
| - recursive: true | |
| args: [--frozen-lockfile, --strict-peer-dependencies] | |
| - name: 'Calculate Next Version' | |
| id: version | |
| run: | | |
| npx tsx scripts/calculate-next-version.ts "${{ github.event.inputs.release_type || 'minor' }}" "${{ github.ref_name }}" | |
| - name: 'Configure Git' | |
| run: | | |
| git config --global user.name "release-automation-${{ github.actor }}" | |
| git config --global user.email "${{ github.actor }}@users.noreply.github.com" | |
| - name: 'Create and Push Tag' | |
| run: | | |
| git tag -a ${{ steps.version.outputs.tag_name }} -m "Release ${{ steps.version.outputs.tag_name }}" | |
| git push origin ${{ steps.version.outputs.tag_name }} | |
| - name: 'Generate Release Notes' | |
| id: release-notes | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| # Get the previous tag | |
| PREV_TAG=$(git describe --tags --abbrev=0 ${{ steps.version.outputs.tag_name }}^ 2>/dev/null || echo "") | |
| if [ -z "$PREV_TAG" ]; then | |
| echo "No previous tag found, this is the first release" | |
| RELEASE_NOTES="Initial release" | |
| else | |
| echo "Previous tag: $PREV_TAG" | |
| echo "Current tag: ${{ steps.version.outputs.tag_name }}" | |
| # Generate release notes using GitHub API | |
| API_RESPONSE=$(gh api \ | |
| --method POST \ | |
| -H "Accept: application/vnd.github+json" \ | |
| -H "X-GitHub-Api-Version: 2022-11-28" \ | |
| /repos/${{ github.repository }}/releases/generate-notes \ | |
| -f tag_name="${{ steps.version.outputs.tag_name }}" \ | |
| -f target_commitish="${{ github.ref_name }}" \ | |
| -f previous_tag_name="$PREV_TAG" 2>/dev/null || echo '{"body": null}') | |
| echo "API Response: $API_RESPONSE" | |
| # Extract the body, with fallback for null values | |
| RELEASE_NOTES=$(echo "$API_RESPONSE" | jq -r '.body // empty') | |
| # If the API didn't return meaningful notes, generate our own | |
| if [ -z "$RELEASE_NOTES" ] || [ "$RELEASE_NOTES" = "null" ]; then | |
| echo "API returned empty/null body, generating custom release notes" | |
| # Get commit messages between tags | |
| COMMITS=$(git log $PREV_TAG..${{ steps.version.outputs.tag_name }} --oneline --pretty=format:"* %s (%h)" 2>/dev/null || echo "") | |
| if [ -n "$COMMITS" ]; then | |
| RELEASE_NOTES="## What's Changed | |
| $COMMITS | |
| **Full Changelog**: https://github.com/${{ github.repository }}/compare/$PREV_TAG...${{ steps.version.outputs.tag_name }}" | |
| else | |
| RELEASE_NOTES="## Release ${{ steps.version.outputs.tag_name }} | |
| This release includes updates and improvements. | |
| **Full Changelog**: https://github.com/${{ github.repository }}/compare/$PREV_TAG...${{ steps.version.outputs.tag_name }}" | |
| fi | |
| fi | |
| fi | |
| echo "Final release notes:" | |
| echo "$RELEASE_NOTES" | |
| # Save to file to handle multi-line content | |
| echo "$RELEASE_NOTES" > release-notes.md | |
| - name: 'Create GitHub Release' | |
| id: create-release | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh release create ${{ steps.version.outputs.tag_name }} \ | |
| --title "Release ${{ steps.version.outputs.tag_name }}" \ | |
| --notes-file release-notes.md \ | |
| --target ${{ github.ref_name }} | |
| build-and-publish: | |
| needs: create-release | |
| runs-on: ubuntu-latest | |
| environment: E2ETesting | |
| permissions: | |
| contents: write | |
| id-token: write # for Azure login | |
| steps: | |
| - name: 'Checkout Github Action' | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ needs.create-release.outputs.tag_name }} | |
| fetch-depth: 0 | |
| - name: 'Set up Node.js' | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - uses: pnpm/action-setup@v3 | |
| with: | |
| version: 9.1.3 | |
| run_install: | | |
| - recursive: true | |
| args: [--frozen-lockfile, --strict-peer-dependencies] | |
| - name: 'Update Version in Package Files' | |
| run: node scripts/update-versions.js ${{ needs.create-release.outputs.new_version }} | |
| - name: 'Set Designer Extension VSIX aiKey in package.json' | |
| run: | | |
| jq --arg key "${{ env.AI_KEY }}" '.aiKey = $key' apps/vs-code-designer/src/package.json > tmp.json | |
| mv tmp.json apps/vs-code-designer/src/package.json | |
| - name: 'Replace Placeholder with Telemetry Key' | |
| run: sed -i "s/setInGitHubBuild/${{ env.AI_KEY }}/g" apps/vs-code-designer/src/main.ts | |
| - name: 'Pack VSCode Designer Extension' | |
| run: pnpm run vscode:designer:pack | |
| - name: 'Archive VSIX' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: vscode-extension | |
| path: | | |
| apps/vs-code-designer/dist/*.vsix | |
| - name: 'Upload VSIX to Release' | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh release upload ${{ needs.create-release.outputs.tag_name }} apps/vs-code-designer/dist/*.vsix --clobber | |
| - name: 'Build Iframe App' | |
| run: pnpm run build --filter @a2achat/iframe-app | |
| env: | |
| BUILD_VERSION: ${{ needs.create-release.outputs.tag_name }} | |
| - name: 'Archive Iframe App' | |
| run: | | |
| # Strip 'v' prefix from tag name (e.g., 'v0.116.1' -> '0.116.1') | |
| VERSION="${{ needs.create-release.outputs.tag_name }}" | |
| VERSION="${VERSION#v}" | |
| mv apps/iframe-app/dist AgentChatIFrames | |
| zip -r AgentChatIFrames-${VERSION}.zip AgentChatIFrames | |
| echo "IFRAME_VERSION=$VERSION" >> $GITHUB_ENV | |
| - name: 'Upload Iframe App to Release' | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh release upload ${{ needs.create-release.outputs.tag_name }} AgentChatIFrames-${IFRAME_VERSION}.zip --clobber | |
| # NPM Publishing | |
| - name: 'Azure login' | |
| uses: azure/login@v2 | |
| with: | |
| client-id: ${{ secrets.AZURE_TESTING_CLIENT_ID }} | |
| tenant-id: ${{ secrets.AZURE_TESTING_TENANT_ID }} | |
| subscription-id: ${{ secrets.AZURE_TESTING_SUBSCRIPTION_ID }} | |
| - name: 'Create Azure Blob Container for Iframe App' | |
| id: create-container | |
| if: ${{ github.event.inputs.enable_blob_upload == 'true' }} | |
| continue-on-error: true | |
| run: | | |
| # Convert tag to valid container name (lowercase, replace dots with hyphens, strip 'v' prefix) | |
| VERSION="${{ needs.create-release.outputs.tag_name }}" | |
| VERSION="${VERSION#v}" | |
| CONTAINER_NAME=$(echo "agentchatiframes-${VERSION}" | tr '[:upper:]' '[:lower:]' | tr '.' '-') | |
| echo "CONTAINER_NAME=$CONTAINER_NAME" >> $GITHUB_ENV | |
| # Check if container already exists | |
| if az storage container exists --account-name agentchatiframes --name "$CONTAINER_NAME" --auth-mode login --query exists -o tsv | grep -q true; then | |
| echo "::warning::Container $CONTAINER_NAME already exists. Skipping blob storage upload." | |
| exit 1 | |
| fi | |
| # Create the container | |
| az storage container create \ | |
| --account-name agentchatiframes \ | |
| --name "$CONTAINER_NAME" \ | |
| --auth-mode login | |
| echo "Created container: $CONTAINER_NAME" | |
| - name: 'Upload Iframe App to Azure Blob Storage' | |
| if: ${{ github.event.inputs.enable_blob_upload == 'true' && steps.create-container.outcome == 'success' }} | |
| run: | | |
| # Upload the zip file | |
| az storage blob upload \ | |
| --account-name agentchatiframes \ | |
| --container-name "$CONTAINER_NAME" \ | |
| --name AgentChatIFrames-${IFRAME_VERSION}.zip \ | |
| --file AgentChatIFrames-${IFRAME_VERSION}.zip \ | |
| --auth-mode login | |
| # Upload all files from the unzipped folder | |
| az storage blob upload-batch \ | |
| --account-name agentchatiframes \ | |
| --destination "$CONTAINER_NAME" \ | |
| --source AgentChatIFrames \ | |
| --auth-mode login | |
| echo "Uploaded zip file and folder contents to container: $CONTAINER_NAME" | |
| - name: 'Generate NPMRC' | |
| shell: bash | |
| run: | | |
| token=`az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798 | jq -r .accessToken` | |
| export ADO_TOKEN=$token | |
| node ./productionNpmRCCreator.js | |
| - name: 'Publish to NPM' | |
| run: pnpm run publish --no-git-checks --access public --tag latest |