Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
name: Release

on:
release:
types: [published]

jobs:
# Job 1: Build and create minor version tag (e.g., v3.2.1)
build-release:
runs-on: ubuntu-latest
environment: release-minor
permissions:
contents: write
outputs:
major: ${{ steps.source.outputs.major }}
env:
TAG_NAME: ${{ github.event.release.tag_name }}

steps:
- name: Validate tag format
run: |
TAG="${{ env.TAG_NAME }}"
if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "❌ Invalid tag format: $TAG"
echo "Tag must match pattern: v<major>.<minor>.<patch> (e.g., v3.2.1)"
exit 1
fi
echo "✅ Valid tag format: $TAG"

- name: Determine source branch
id: source
run: |
TAG="${{ env.TAG_NAME }}"
MAJOR=$(echo "$TAG" | sed 's/v//' | cut -d. -f1)
# Map major version to release branch (releases/v2, releases/v3, etc.)
echo "branch=releases/v${MAJOR}" >> $GITHUB_OUTPUT
echo "major=v${MAJOR}" >> $GITHUB_OUTPUT

- name: Checkout source branch
uses: actions/checkout@v4
with:
ref: ${{ steps.source.outputs.branch }}
fetch-depth: 0

- name: Show changes being released
env:
MAJOR: ${{ steps.source.outputs.major }}
BRANCH: ${{ steps.source.outputs.branch }}
run: |
# Get previous tag for this major version
PREV_TAG=$(git tag --sort=-v:refname | grep -E "^${MAJOR}\.[0-9]+\.[0-9]+$" | head -1)

echo "## 📋 Changes being released in ${{ env.TAG_NAME }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Source branch:** \`${BRANCH}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

if [ -n "$PREV_TAG" ]; then
echo "### Commits since $PREV_TAG" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
git log --oneline ${PREV_TAG}..HEAD >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Files changed" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
git diff --stat ${PREV_TAG}..HEAD >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "🔗 [View full diff](https://github.com/${{ github.repository }}/compare/${PREV_TAG}...${BRANCH})" >> $GITHUB_STEP_SUMMARY
else
echo "First release for ${MAJOR} - no previous tag found" >> $GITHUB_STEP_SUMMARY
fi

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Update version file
run: |
echo "// This file is auto-updated during release" > src/version.ts
echo "export const VERSION = '${{ env.TAG_NAME }}';" >> src/version.ts
cat src/version.ts

- name: Build TypeScript
run: npm run build

- name: Bundle with ncc
run: |
npm install -g @vercel/ncc
ncc build lib/main.js -o dist

- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Commit dist and create minor tag
run: |
# Add dist folder (force add even if in .gitignore)
git add dist/ -f
git commit -m "Build dist for release ${{ env.TAG_NAME }}"

# Update the release tag to include dist
git tag -fa ${{ env.TAG_NAME }} -m "Release ${{ env.TAG_NAME }}"

# Push minor version tag
git push origin ${{ env.TAG_NAME }} --force

echo "## ✅ Minor tag ${{ env.TAG_NAME }} created" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Users can now use: \`Azure/webapps-deploy@${{ env.TAG_NAME }}\`" >> $GITHUB_STEP_SUMMARY

# Job 2: Update major version tag (e.g., v3 -> v3.2.1)
update-major-tag:
needs: build-release
runs-on: ubuntu-latest
environment: release-major
permissions:
contents: write
env:
TAG_NAME: ${{ github.event.release.tag_name }}

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Update major tag to point to minor
env:
MAJOR: ${{ needs.build-release.outputs.major }}
run: |
# Fetch the minor tag
git fetch origin tag ${{ env.TAG_NAME }} --no-tags

# Update major version tag to point to minor tag
git tag -fa ${MAJOR} ${{ env.TAG_NAME }} -m "Point ${MAJOR} to ${{ env.TAG_NAME }}"

# Push major version tag
git push origin ${MAJOR} --force

echo "## ✅ Major tag ${MAJOR} now points to ${{ env.TAG_NAME }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Users on \`Azure/webapps-deploy@${MAJOR}\` will now get ${{ env.TAG_NAME }}" >> $GITHUB_STEP_SUMMARY
172 changes: 172 additions & 0 deletions .github/workflows/test-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
name: Test Release Build

on:
workflow_dispatch:
inputs:
tag_name:
description: 'Tag to simulate (e.g., v3.2.1)'
required: true
type: string
test_branch_name:
description: 'Test branch name to push (e.g., test-release-v3)'
required: true
type: string
default: 'test-release'
test_deploy:
description: 'Test deployment to an app after build'
required: false
type: boolean
default: false
test_app_name:
description: 'App name for test deployment (required if test_deploy is true)'
required: false
type: string

jobs:
build-and-push-test-branch:
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
branch: ${{ steps.source.outputs.branch }}

steps:
- name: Validate tag format
run: |
TAG="${{ inputs.tag_name }}"
if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "❌ Invalid tag format: $TAG"
echo "Tag must match pattern: v<major>.<minor>.<patch> (e.g., v3.2.1)"
exit 1
fi
echo "✅ Valid tag format: $TAG"

- name: Determine source branch
id: source
run: |
TAG="${{ inputs.tag_name }}"
MAJOR=$(echo "$TAG" | sed 's/v//' | cut -d. -f1)
echo "branch=releases/v${MAJOR}" >> $GITHUB_OUTPUT
echo "major=v${MAJOR}" >> $GITHUB_OUTPUT

- name: Checkout source branch
uses: actions/checkout@v4
with:
ref: ${{ steps.source.outputs.branch }}
fetch-depth: 0

- name: Show what will be built
env:
MAJOR: ${{ steps.source.outputs.major }}
BRANCH: ${{ steps.source.outputs.branch }}
run: |
PREV_TAG=$(git tag --sort=-v:refname | grep -E "^${MAJOR}\.[0-9]+\.[0-9]+$" | head -1)

echo "## 🧪 Test Build for ${{ inputs.tag_name }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Source branch:** \`${BRANCH}\`" >> $GITHUB_STEP_SUMMARY
echo "**Test branch:** \`${{ inputs.test_branch_name }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

if [ -n "$PREV_TAG" ]; then
echo "### Changes since $PREV_TAG" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
git log --oneline ${PREV_TAG}..HEAD >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
fi

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Update version file
run: |
echo "// This file is auto-updated during release" > src/version.ts
echo "export const VERSION = '${{ inputs.tag_name }}';" >> src/version.ts
cat src/version.ts

- name: Build TypeScript
run: npm run build

- name: Bundle with ncc
run: |
npm install -g @vercel/ncc
ncc build lib/main.js -o dist

- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Commit and push test branch
env:
TEST_BRANCH: ${{ inputs.test_branch_name }}
run: |
# Add dist folder
git add dist/ -f
git commit -m "Test build for ${{ inputs.tag_name }}"

# Create and push test branch
git checkout -b ${TEST_BRANCH}
git push origin ${TEST_BRANCH} --force

echo "## ✅ Test branch pushed" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "You can now test with:" >> $GITHUB_STEP_SUMMARY
echo '```yaml' >> $GITHUB_STEP_SUMMARY
echo "- uses: Azure/webapps-deploy@${TEST_BRANCH}" >> $GITHUB_STEP_SUMMARY
echo " with:" >> $GITHUB_STEP_SUMMARY
echo " app-name: your-app-name" >> $GITHUB_STEP_SUMMARY
echo " package: ./your-package" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Cleanup" >> $GITHUB_STEP_SUMMARY
echo "After testing, delete the branch:" >> $GITHUB_STEP_SUMMARY
echo '```bash' >> $GITHUB_STEP_SUMMARY
echo "git push origin --delete ${TEST_BRANCH}" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY

# Optional: Test deployment using the pushed branch
test-deployment:
if: inputs.test_deploy == true && inputs.test_app_name != ''
needs: build-and-push-test-branch
runs-on: ubuntu-latest

steps:
- name: Checkout test branch
uses: actions/checkout@v4
with:
ref: ${{ inputs.test_branch_name }}

- name: Create test package
run: |
mkdir -p test-app
cat > test-app/index.html << EOF
<html>
<body>
<h1>Test Deployment</h1>
<p>Version: ${{ inputs.tag_name }}</p>
<p>Branch: ${{ inputs.test_branch_name }}</p>
<p>Time: $(date)</p>
</body>
</html>
EOF

- name: Test deploy to Azure Web App
uses: ./
with:
app-name: ${{ inputs.test_app_name }}
package: test-app

- name: Test deployment result
run: |
echo "## 🚀 Test Deployment Successful" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "✅ Deployed to: **${{ inputs.test_app_name }}**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "🔗 Verify at: https://${{ inputs.test_app_name }}.azurewebsites.net" >> $GITHUB_STEP_SUMMARY
Comment on lines +136 to +172

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium test

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI about 21 hours ago

In general, to fix this class of problem you should add an explicit permissions block at the workflow or job level that grants only the minimal scopes required. Jobs that only need to read code (for checkout) can typically use contents: read. Jobs that need to push commits or create tags require contents: write, and more specialized operations (e.g., interacting with issues or PRs) should use the corresponding fine-grained permissions.

For this specific workflow, the build-and-push-test-branch job already has permissions: contents: write, which is appropriate because it commits and pushes a branch. The flagged test-deployment job, however, only checks out code and performs a deployment using a local action. There’s no evidence it needs write access to the repository itself. The best fix while preserving existing behavior is to add a permissions block to test-deployment that limits the GITHUB_TOKEN to read-only repository contents. Concretely, in .github/workflows/test-release.yml, within the test-deployment job (around line 135), add:

permissions:
  contents: read

just under the job name (and before or after if: / needs: / runs-on: — order among job keys doesn’t affect semantics). No other code or imports are needed.

Suggested changeset 1
.github/workflows/test-release.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/test-release.yml b/.github/workflows/test-release.yml
--- a/.github/workflows/test-release.yml
+++ b/.github/workflows/test-release.yml
@@ -136,6 +136,8 @@
     if: inputs.test_deploy == true && inputs.test_app_name != ''
     needs: build-and-push-test-branch
     runs-on: ubuntu-latest
+    permissions:
+      contents: read
     
     steps:
       - name: Checkout test branch
EOF
@@ -136,6 +136,8 @@
if: inputs.test_deploy == true && inputs.test_app_name != ''
needs: build-and-push-test-branch
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout test branch
Copilot is powered by AI and may make mistakes. Always verify output.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore

# Bundled output (built during release)
dist/

# User-specific files
*.suo
*.user
Expand Down
2 changes: 1 addition & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ branding:
color: 'blue'
runs:
using: 'node20'
main: 'lib/main.js'
main: 'dist/index.js'
Loading
Loading