diff --git a/.github/workflows/check-models.yml b/.github/workflows/check-models.yml index f1679242..736a5a26 100644 --- a/.github/workflows/check-models.yml +++ b/.github/workflows/check-models.yml @@ -99,7 +99,7 @@ jobs: echo "" echo "=== Copilot CLI Output ===" - cd ${GITHUB_WORKSPACE} + cd "${GITHUB_WORKSPACE}" # Run copilot with the prompt using non-interactive mode COPILOT_PROMPT_TEXT=$(cat /tmp/copilot-prompt.md) @@ -113,29 +113,29 @@ jobs: run: | if git diff --quiet src/tokenEstimators.json src/modelPricing.json; then echo "No changes detected in model data files" - echo "changed=false" >> $GITHUB_OUTPUT + echo "changed=false" >> "$GITHUB_OUTPUT" else # Check if the only change is the lastUpdated date in modelPricing.json DIFF_OUTPUT=$(git diff src/modelPricing.json) # Count the number of changed lines (lines starting with +/- but not +++ or ---) - CHANGED_LINES=$(echo "$DIFF_OUTPUT" | grep -E '^[+-][^+-]' | wc -l) + CHANGED_LINES=$(echo "$DIFF_OUTPUT" | grep -cE '^[+-][^+-]' || true) # Check if only 2 lines changed (one deletion, one addition) and both contain "lastUpdated" if [ "$CHANGED_LINES" -eq 2 ]; then # Check if all changed lines contain "lastUpdated" - if echo "$DIFF_OUTPUT" | grep -E '^[+-][^+-]' | grep -v '"lastUpdated"' | wc -l | grep -q '^0$'; then + if ! echo "$DIFF_OUTPUT" | grep -E '^[+-][^+-]' | grep -qv '"lastUpdated"'; then # Verify no changes to tokenEstimators.json if git diff --quiet src/tokenEstimators.json; then echo "Only lastUpdated date changed - skipping PR creation" - echo "changed=false" >> $GITHUB_OUTPUT + echo "changed=false" >> "$GITHUB_OUTPUT" exit 0 fi fi fi echo "Changes detected in model data files" - echo "changed=true" >> $GITHUB_OUTPUT + echo "changed=true" >> "$GITHUB_OUTPUT" fi - name: Create Pull Request diff --git a/.github/workflows/cli-publish.yml b/.github/workflows/cli-publish.yml index 3d0a36cb..5b129e1c 100644 --- a/.github/workflows/cli-publish.yml +++ b/.github/workflows/cli-publish.yml @@ -100,14 +100,16 @@ jobs: - name: Summary run: | - echo "## CLI Package Published 📦" >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - echo "- **Version:** v${{ steps.version.outputs.version }}" >> "$GITHUB_STEP_SUMMARY" - echo "- **Bump:** ${{ inputs.version_bump }}" >> "$GITHUB_STEP_SUMMARY" - echo "- **Dry run:** ${{ inputs.dry_run }}" >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - if [ "${{ inputs.dry_run }}" = "false" ]; then - echo "Install with: \`npx @rajbos/ai-engineering-fluency\`" >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - echo "A PR has been opened to merge the version bump back to main." >> "$GITHUB_STEP_SUMMARY" - fi + { + echo "## CLI Package Published 📦" + echo "" + echo "- **Version:** v${{ steps.version.outputs.version }}" + echo "- **Bump:** ${{ inputs.version_bump }}" + echo "- **Dry run:** ${{ inputs.dry_run }}" + echo "" + if [ "${{ inputs.dry_run }}" = "false" ]; then + echo "Install with: \`npx @rajbos/ai-engineering-fluency\`" + echo "" + echo "A PR has been opened to merge the version bump back to main." + fi + } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 5e6074ce..9c861d3e 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -154,19 +154,19 @@ jobs: echo "Date range: $START_DATE to $END_DATE" # Build command arguments - ARGS="--storageAccount $AZURE_STORAGE_ACCOUNT" - ARGS="$ARGS --tableName $AZURE_TABLE_NAME" - ARGS="$ARGS --datasetId $AZURE_DATASET_ID" - ARGS="$ARGS --startDate $START_DATE" - ARGS="$ARGS --endDate $END_DATE" - ARGS="$ARGS --output ./usage-data/usage-agg-daily.json" + ARGS=(--storageAccount "$AZURE_STORAGE_ACCOUNT") + ARGS+=(--tableName "$AZURE_TABLE_NAME") + ARGS+=(--datasetId "$AZURE_DATASET_ID") + ARGS+=(--startDate "$START_DATE") + ARGS+=(--endDate "$END_DATE") + ARGS+=(--output ./usage-data/usage-agg-daily.json) # Use shared key if available, otherwise rely on Entra ID (DefaultAzureCredential) if [ -n "$AZURE_STORAGE_KEY" ]; then - ARGS="$ARGS --sharedKey $AZURE_STORAGE_KEY" + ARGS+=(--sharedKey "$AZURE_STORAGE_KEY") fi - node .github/skills/azure-storage-loader/load-table-data.js $ARGS || { + node .github/skills/azure-storage-loader/load-table-data.js "${ARGS[@]}" || { echo "⚠️ Failed to download aggregated usage data, continuing without it" exit 0 } diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b040a30c..81b9a429 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -49,10 +49,10 @@ jobs: id: trigger_type run: | if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - echo "is_manual=true" >> $GITHUB_OUTPUT + echo "is_manual=true" >> "$GITHUB_OUTPUT" echo "Triggered manually via workflow_dispatch" else - echo "is_manual=false" >> $GITHUB_OUTPUT + echo "is_manual=false" >> "$GITHUB_OUTPUT" echo "Triggered by tag push" fi @@ -60,7 +60,7 @@ jobs: id: package_version run: | PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "package_version=$PACKAGE_VERSION" >> $GITHUB_OUTPUT + echo "package_version=$PACKAGE_VERSION" >> "$GITHUB_OUTPUT" echo "Package version: $PACKAGE_VERSION" - name: Extract version from tag @@ -73,7 +73,7 @@ jobs: # For tag triggers, extract from the tag TAG_VERSION=${GITHUB_REF#refs/tags/v} fi - echo "tag_version=$TAG_VERSION" >> $GITHUB_OUTPUT + echo "tag_version=$TAG_VERSION" >> "$GITHUB_OUTPUT" echo "Release version: $TAG_VERSION" - name: Verify version consistency @@ -95,7 +95,7 @@ jobs: else TAG_NAME="${{ github.ref_name }}" fi - echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT + echo "tag_name=$TAG_NAME" >> "$GITHUB_OUTPUT" echo "Tag name: $TAG_NAME" - name: Generate release notes @@ -150,7 +150,7 @@ jobs: run: | VERSION="${{ steps.extract_version.outputs.tag_version }}" BRANCH="changelog/v${VERSION}" - echo "branch=$BRANCH" >> $GITHUB_OUTPUT + echo "branch=$BRANCH" >> "$GITHUB_OUTPUT" git config --local user.name "github-actions[bot]" git config --local user.email "github-actions[bot]@users.noreply.github.com" @@ -239,8 +239,8 @@ jobs: - name: Get VSIX filename id: vsix_filename run: | - VSIX_FILE=$(ls *.vsix | head -n 1) - echo "vsix_file=$VSIX_FILE" >> $GITHUB_OUTPUT + VSIX_FILE=$(find . -maxdepth 1 -name "*.vsix" -exec basename {} \; | head -n 1) + echo "vsix_file=$VSIX_FILE" >> "$GITHUB_OUTPUT" echo "VSIX file: $VSIX_FILE" - name: Upload VSIX as workflow artifact @@ -270,26 +270,30 @@ jobs: if: always() run: | if [ "${{ steps.create_release.outcome }}" == "success" ]; then - echo "# ✅ Release Created Successfully" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "🎉 Release ${{ steps.extract_version.outputs.tag_version }} created successfully!" >> $GITHUB_STEP_SUMMARY - echo "📦 VSIX package: ${{ steps.vsix_filename.outputs.vsix_file }}" >> $GITHUB_STEP_SUMMARY - echo "🔗 [Release URL](https://github.com/${{ github.repository }}/releases/tag/${{ steps.tag_name.outputs.tag_name }})" >> $GITHUB_STEP_SUMMARY + { + echo "# ✅ Release Created Successfully" + echo "" + echo "🎉 Release ${{ steps.extract_version.outputs.tag_version }} created successfully!" + echo "📦 VSIX package: ${{ steps.vsix_filename.outputs.vsix_file }}" + echo "🔗 [Release URL](https://github.com/${{ github.repository }}/releases/tag/${{ steps.tag_name.outputs.tag_name }})" + } >> "$GITHUB_STEP_SUMMARY" else - echo "# ❌ Release Creation Failed" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "**Version:** ${{ steps.extract_version.outputs.tag_version }}" >> $GITHUB_STEP_SUMMARY - echo "**Tag:** ${{ steps.tag_name.outputs.tag_name }}" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "## Error Details" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "\`\`\`" >> $GITHUB_STEP_SUMMARY - if [ -f /tmp/release_output.txt ]; then - cat /tmp/release_output.txt >> $GITHUB_STEP_SUMMARY - else - echo "No error details captured" >> $GITHUB_STEP_SUMMARY - fi - echo "\`\`\`" >> $GITHUB_STEP_SUMMARY + { + echo "# ❌ Release Creation Failed" + echo "" + echo "**Version:** ${{ steps.extract_version.outputs.tag_version }}" + echo "**Tag:** ${{ steps.tag_name.outputs.tag_name }}" + echo "" + echo "## Error Details" + echo "" + echo "\`\`\`" + if [ -f /tmp/release_output.txt ]; then + cat /tmp/release_output.txt + else + echo "No error details captured" + fi + echo "\`\`\`" + } >> "$GITHUB_STEP_SUMMARY" exit 1 fi @@ -329,9 +333,9 @@ jobs: --repo "${{ github.repository }}" \ --pattern "*.vsix" \ --dir . - VSIX_FILE=$(ls *.vsix | head -n 1) + VSIX_FILE=$(find . -maxdepth 1 -name "*.vsix" -exec basename {} \; | head -n 1) echo "Downloaded: $VSIX_FILE" - echo "vsix_file=$VSIX_FILE" >> $GITHUB_OUTPUT + echo "vsix_file=$VSIX_FILE" >> "$GITHUB_OUTPUT" - name: Publish to VS Code Marketplace id: publish @@ -353,15 +357,17 @@ jobs: - name: Publish Summary if: always() run: | - echo "# 🚀 VS Code Marketplace" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - if [ "${{ steps.publish.outcome }}" == "success" ]; then - echo "✅ Extension v${{ needs.release.outputs.version }} published to the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=RobBos.copilot-token-tracker)" >> $GITHUB_STEP_SUMMARY - else - echo "❌ Failed to publish v${{ needs.release.outputs.version }} to marketplace." >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "Ensure the \`VSCE_PAT\` secret is configured with a valid Azure DevOps PAT" >> $GITHUB_STEP_SUMMARY - echo "with the \`Marketplace (Publish)\` scope for all accessible organizations." >> $GITHUB_STEP_SUMMARY - fi + { + echo "# 🚀 VS Code Marketplace" + echo "" + if [ "${{ steps.publish.outcome }}" == "success" ]; then + echo "✅ Extension v${{ needs.release.outputs.version }} published to the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=RobBos.copilot-token-tracker)" + else + echo "❌ Failed to publish v${{ needs.release.outputs.version }} to marketplace." + echo "" + echo "Ensure the \`VSCE_PAT\` secret is configured with a valid Azure DevOps PAT" + echo "with the \`Marketplace (Publish)\` scope for all accessible organizations." + fi + } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/sync-release-notes.yml b/.github/workflows/sync-release-notes.yml index 1c46983e..7025500b 100644 --- a/.github/workflows/sync-release-notes.yml +++ b/.github/workflows/sync-release-notes.yml @@ -40,10 +40,10 @@ jobs: id: changes run: | if git diff --quiet CHANGELOG.md; then - echo "changed=false" >> $GITHUB_OUTPUT + echo "changed=false" >> "$GITHUB_OUTPUT" echo "No changes detected in CHANGELOG.md" else - echo "changed=true" >> $GITHUB_OUTPUT + echo "changed=true" >> "$GITHUB_OUTPUT" echo "Changes detected in CHANGELOG.md" fi diff --git a/.github/workflows/sync-toolnames.yml b/.github/workflows/sync-toolnames.yml index 1ad9a397..d43f1f7a 100644 --- a/.github/workflows/sync-toolnames.yml +++ b/.github/workflows/sync-toolnames.yml @@ -113,7 +113,7 @@ jobs: echo "" echo "=== Copilot CLI Output ===" - cd ${GITHUB_WORKSPACE}/current-repo/ + cd "${GITHUB_WORKSPACE}/current-repo/" # Run gh copilot with the prompt using non-interactive mode # Use -s/--silent for script-friendly output, -p for prompt, --allow-all for permissions @@ -132,10 +132,10 @@ jobs: run: | if git diff --quiet; then echo "No changes detected in toolNames.json" - echo "changed=false" >> $GITHUB_OUTPUT + echo "changed=false" >> "$GITHUB_OUTPUT" else echo "Changes detected in toolNames.json" - echo "changed=true" >> $GITHUB_OUTPUT + echo "changed=true" >> "$GITHUB_OUTPUT" fi - name: Create Pull Request diff --git a/.github/workflows/validate-skills.yml b/.github/workflows/validate-skills.yml index 063f7a51..05dff27d 100644 --- a/.github/workflows/validate-skills.yml +++ b/.github/workflows/validate-skills.yml @@ -55,7 +55,7 @@ jobs: sort -u | \ jq -R -s -c 'split("\n") | map(select(length > 0))') - echo "skills=$SKILLS" >> $GITHUB_OUTPUT + echo "skills=$SKILLS" >> "$GITHUB_OUTPUT" echo "Changed skills: $SKILLS" validate: