Skip to content

ci: Bump actions/checkout from 4.3.1 to 6.0.2 #27

ci: Bump actions/checkout from 4.3.1 to 6.0.2

ci: Bump actions/checkout from 4.3.1 to 6.0.2 #27

Workflow file for this run

name: Release

Check failure on line 1 in .github/workflows/release.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/release.yml

Invalid workflow file

(Line: 152, Col: 30): Job 'release' depends on unknown job 'build'.
on:
workflow_dispatch:
inputs:
bump:
description: 'Version bump type'
required: true
type: choice
options:
- patch
- minor
- major
env:
GO_VERSION: '1.26.1'
concurrency:
group: release
cancel-in-progress: false
jobs:
preflight:
name: Preflight Checks
runs-on: ubuntu-latest
timeout-minutes: 30
defaults:
run:
working-directory: cli
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: '${{ env.GO_VERSION }}'
cache: true
cache-dependency-path: cli/go.sum
- name: Cache Go tools
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4
with:
path: ~/go/bin
key: go-tools-${{ runner.os }}-${{ hashFiles('cli/go.sum') }}
- name: Install golangci-lint
run: go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
- name: Install staticcheck
run: go install honnef.co/go/tools/cmd/staticcheck@latest
- name: Install gosec
run: go install github.com/securego/gosec/v2/cmd/gosec@latest
- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
- name: Install azd
run: curl -fsSL https://aka.ms/install-azd.sh | bash
- name: Install azd extensions
run: |
azd extension source add azd --location https://aka.ms/azd/extensions/registry --type url 2>/dev/null || true
azd extension install microsoft.azd.extensions --source azd
- name: Format check
run: |
if [ -n "$(gofmt -l ./src/)" ]; then
echo "Go files need formatting:"
gofmt -l ./src/
exit 1
fi
- name: Lint
run: golangci-lint run --timeout=5m ./src/...
- name: Security scan
run: gosec -quiet -exclude=G204,G304 ./src/...
- name: Vulnerability check
run: govulncheck ./src/...
test:
name: Test
runs-on: ${{ matrix.os }}
timeout-minutes: 30
defaults:
run:
working-directory: cli
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: '${{ env.GO_VERSION }}'
cache: true
cache-dependency-path: cli/go.sum
- name: Run tests
shell: bash
run: |
mkdir -p ../coverage
if [ "${{ matrix.os }}" = "macos-latest" ]; then
go test -short -v -coverprofile=../coverage/coverage.out ./src/...
else
go test -short -v -race -coverprofile=../coverage/coverage.out ./src/...
fi
- name: Upload coverage to Codecov
if: github.repository == 'jongio/azd-rest'
uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4
with:
file: coverage/coverage.out
flags: unittests
name: codecov-${{ matrix.os }}-go-${{ env.GO_VERSION }}
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false
verbose: true
- name: Set up Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: '${{ env.GO_VERSION }}'
cache: true
cache-dependency-path: cli/go.sum
- name: Build for multiple platforms
run: |
GOOS=windows GOARCH=amd64 go build -o bin/windows-amd64/rest.exe ./src/cmd/rest
GOOS=windows GOARCH=arm64 go build -o bin/windows-arm64/rest.exe ./src/cmd/rest
GOOS=linux GOARCH=amd64 go build -o bin/linux-amd64/rest ./src/cmd/rest
GOOS=darwin GOARCH=amd64 go build -o bin/darwin-amd64/rest ./src/cmd/rest
GOOS=darwin GOARCH=arm64 go build -o bin/darwin-arm64/rest ./src/cmd/rest
- name: Upload artifacts
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: binaries
path: cli/bin/
release:
name: Release
runs-on: ubuntu-latest
needs: [preflight, test, build]
timeout-minutes: 60
permissions:
contents: write
pull-requests: write
id-token: write # Required for cosign OIDC signing
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: '${{ env.GO_VERSION }}'
cache: true
cache-dependency-path: cli/go.sum
- name: Calculate next version
id: version
run: |
CURRENT=$(grep '^version:' cli/extension.yaml | awk '{print $2}')
IFS='.' read -r major minor patch <<< "$CURRENT"
case "${{ inputs.bump }}" in
major)
major=$((major + 1))
minor=0
patch=0
;;
minor)
minor=$((minor + 1))
patch=0
;;
patch)
patch=$((patch + 1))
;;
esac
NEXT="$major.$minor.$patch"
echo "current=$CURRENT" >> $GITHUB_OUTPUT
echo "next=$NEXT" >> $GITHUB_OUTPUT
echo "Bumping from $CURRENT to $NEXT"
- name: Update version files and create PR
id: version_pr
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ steps.version.outputs.next }}"
BRANCH="release/v${VERSION}"
git push origin --delete "$BRANCH" 2>/dev/null || true
git branch -D "$BRANCH" 2>/dev/null || true
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git checkout -b "$BRANCH"
sed -i "s/^version: .*/version: $VERSION/" cli/extension.yaml
PREV="${{ steps.version.outputs.current }}"
if git rev-parse "v${PREV}" >/dev/null 2>&1; then
COMMITS=$(git log --pretty=format:"- %s (%h)" --no-merges v${PREV}..HEAD)
else
LAST_VERSION_COMMIT=$(git log --grep="^chore: bump version to" --format="%H" -n 1)
if [ -n "$LAST_VERSION_COMMIT" ]; then
COMMITS=$(git log --pretty=format:"- %s (%h)" --no-merges ${LAST_VERSION_COMMIT}..HEAD)
else
COMMITS=$(git log --pretty=format:"- %s (%h)" --no-merges)
fi
fi
DATE=$(date +%Y-%m-%d)
{
echo "## [$VERSION] - $DATE"
echo ""
echo "$COMMITS"
echo ""
cat CHANGELOG.md
} > CHANGELOG.new.md
mv CHANGELOG.new.md CHANGELOG.md
git add cli/extension.yaml CHANGELOG.md
git commit -m "chore: bump version to $VERSION"
git push origin "$BRANCH"
PR_URL=$(gh pr create \
--title "chore: Release v${VERSION}" \
--body "Automated version bump to ${VERSION} for release." \
--base main \
--head "$BRANCH")
echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT
echo "branch=$BRANCH" >> $GITHUB_OUTPUT
PR_NUMBER=$(echo "$PR_URL" | grep -oP '\d+$')
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
- name: Enable auto-merge and wait for merge
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUMBER="${{ steps.version_pr.outputs.pr_number }}"
echo "Waiting for CI checks to be queued..."
sleep 10
MAX_RETRIES=3
RETRY=0
while [ $RETRY -lt $MAX_RETRIES ]; do
if gh pr merge "$PR_NUMBER" --auto --squash 2>&1; then
echo "Auto-merge enabled successfully!"
break
else
RETRY=$((RETRY + 1))
if [ $RETRY -lt $MAX_RETRIES ]; then
echo "Retrying in 10 seconds... (attempt $RETRY/$MAX_RETRIES)"
sleep 10
else
echo "Failed to enable auto-merge after $MAX_RETRIES attempts"
exit 1
fi
fi
done
echo "Waiting for PR to be merged..."
TIMEOUT=600
ELAPSED=0
INTERVAL=15
while [ $ELAPSED -lt $TIMEOUT ]; do
PR_DATA=$(gh pr view "$PR_NUMBER" --json state,mergeable,statusCheckRollup)
STATE=$(echo "$PR_DATA" | jq -r '.state')
MERGEABLE=$(echo "$PR_DATA" | jq -r '.mergeable')
echo "PR state: $STATE, Mergeable: $MERGEABLE"
if [ "$STATE" = "MERGED" ]; then
echo "PR merged successfully!"
break
fi
PENDING_CHECKS=$(echo "$PR_DATA" | jq '[.statusCheckRollup[] | select(.status == "IN_PROGRESS" or .status == "QUEUED" or .status == "PENDING")] | length')
TOTAL_CHECKS=$(echo "$PR_DATA" | jq '.statusCheckRollup | length')
echo "Checks: $((TOTAL_CHECKS - PENDING_CHECKS))/$TOTAL_CHECKS complete"
if [ "$PENDING_CHECKS" -eq 0 ] && [ "$TOTAL_CHECKS" -gt 0 ]; then
FAILED_CHECKS=$(echo "$PR_DATA" | jq -r '.statusCheckRollup[] | select(.conclusion == "FAILURE" or .conclusion == "CANCELLED") | .name')
if [ -n "$FAILED_CHECKS" ]; then
echo "ERROR: Some checks failed:"
echo "$FAILED_CHECKS"
exit 1
fi
fi
sleep $INTERVAL
ELAPSED=$((ELAPSED + INTERVAL))
done
if [ "$STATE" != "MERGED" ]; then
echo "ERROR: PR did not merge within timeout"
exit 1
fi
- name: Checkout main and create tag
run: |
VERSION="${{ steps.version.outputs.next }}"
git checkout main
git pull origin main
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Delete existing tag if present (from a previous failed run)
git tag -d "v${VERSION}" 2>/dev/null || true
git push origin --delete "v${VERSION}" 2>/dev/null || true
git tag -a "v${VERSION}" -m "Release version ${VERSION}"
git push origin "v${VERSION}"
- name: Install azd
run: curl -fsSL https://aka.ms/install-azd.sh | bash
- name: Install azd extensions
run: |
azd extension source add azd --location https://aka.ms/azd/extensions/registry --type url 2>/dev/null || true
azd extension install microsoft.azd.extensions --source azd
- name: Build binaries
working-directory: cli
run: |
export EXTENSION_ID="jongio.azd.rest"
export EXTENSION_VERSION="${{ steps.version.outputs.next }}"
azd x build --all
- name: Package
working-directory: cli
run: azd x pack
- name: Extract release notes
id: release_notes
run: |
VERSION="${{ steps.version.outputs.next }}"
awk '
BEGIN { in_section = 0 }
/^## \['"$VERSION"'\]/ { in_section = 1; next }
/^## \[/ { in_section = 0 }
in_section && NF > 0 { print }
' CHANGELOG.md > /tmp/release-notes.md
echo "Release notes for v$VERSION:"
cat /tmp/release-notes.md
- name: Release
working-directory: cli
run: |
VERSION="${{ steps.version.outputs.next }}"
TAG_NAME="azd-ext-jongio-azd-rest_${VERSION}"
# Delete existing release if present (from a previous failed run)
gh release delete "$TAG_NAME" --yes 2>/dev/null || true
azd x release \
--repo "${{ github.repository }}" \
--version "$VERSION" \
--notes-file /tmp/release-notes.md \
--confirm
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install cosign
uses: sigstore/cosign-installer@3454372be43e8ddeec39df0f73bb47954da3a1f1 # v3
- name: Install syft
uses: anchore/sbom-action/download-syft@57aae528053a48a3f6235f2d9461b05fbcb7366d # v0
- name: Sign release artifacts with cosign
working-directory: cli
run: |
VERSION="${{ steps.version.outputs.next }}"
TAG_NAME="azd-ext-jongio-azd-rest_${VERSION}"
echo "Signing release artifacts for ${TAG_NAME}..."
# Download release assets
gh release download "${TAG_NAME}" --dir /tmp/release-assets --repo "${{ github.repository }}" || true
# Sign each artifact
if [ -d /tmp/release-assets ]; then
for file in /tmp/release-assets/*; do
if [ -f "$file" ]; then
echo "Signing $(basename $file)..."
cosign sign-blob --yes "$file" --output-signature "${file}.sig" --output-certificate "${file}.pem"
fi
done
# Upload signatures and certificates to the release
gh release upload "${TAG_NAME}" /tmp/release-assets/*.sig /tmp/release-assets/*.pem --repo "${{ github.repository }}" || true
echo "✅ All artifacts signed with cosign (keyless/OIDC)"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Generate SBOM
working-directory: cli
run: |
VERSION="${{ steps.version.outputs.next }}"
TAG_NAME="azd-ext-jongio-azd-rest_${VERSION}"
echo "Generating SBOM for ${TAG_NAME}..."
# Generate SBOM for the Go module
syft . -o spdx-json=/tmp/sbom-spdx.json -o cyclonedx-json=/tmp/sbom-cyclonedx.json
# Upload SBOM to the release
gh release upload "${TAG_NAME}" /tmp/sbom-spdx.json /tmp/sbom-cyclonedx.json --repo "${{ github.repository }}" || true
echo "✅ SBOM generated and uploaded (SPDX + CycloneDX)"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Update registry
working-directory: cli
run: |
azd x publish \
--registry ../registry.json \
--version "${{ steps.version.outputs.next }}" \
--repo "${{ github.repository }}"
cd ..
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add registry.json
if ! git diff --cached --quiet; then
git commit -m "chore: update registry for v${{ steps.version.outputs.next }}"
git push
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}