From f94a43b069458a7a2241c9ec51aa1729d417c4aa Mon Sep 17 00:00:00 2001 From: "Tom Meschter (from Dev Box)" Date: Wed, 5 Aug 2026 13:44:41 -0700 Subject: [PATCH 1/7] feat: validate executable shell scripts Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/copilot-instructions.md | 2 + .github/workflows/pr.yml | 15 ++++++ package.json | 1 + .../scaffold/scripts/scaffold-conformance.sh | 0 .../recipes/azd/scripts/apply-migrations.sh | 0 .../recipes/azd/scripts/grant-and-migrate.sh | 0 .../azure-diagnostics/scripts/aks-baseline.sh | 0 .../sql-database/scripts/grant-sql-access.sh | 0 .../azure-quotas/scripts/check-quota.sh | 0 .../recipes/azd/scripts/set-aspire-aca-env.sh | 0 .../scripts/scan-aspire-functions-secrets.sh | 0 .../references/scripts/workflow.sh | 0 .../create/scripts/check-copilot-app-entry.sh | 0 .../create/scripts/resolve-project-id.sh | 0 .../create/scripts/verify-environment.sh | 0 .../toolbox/scripts/get-catalog-inputs.sh | 0 .../capacity/scripts/discover_and_rank.sh | 0 .../capacity/scripts/query_capacity.sh | 0 .../scripts/generate_deployment_url.sh | 0 .../scripts/check-and-setup-dependencies.sh | 0 scripts/package.json | 1 + scripts/src/check-shell-script-permissions.ts | 49 +++++++++++++++++++ 22 files changed, 68 insertions(+) mode change 100644 => 100755 plugins/azure-skills/skills/azure-app-onboard/scaffold/scripts/scaffold-conformance.sh mode change 100644 => 100755 plugins/azure-skills/skills/azure-deploy/references/recipes/azd/scripts/apply-migrations.sh mode change 100644 => 100755 plugins/azure-skills/skills/azure-deploy/references/recipes/azd/scripts/grant-and-migrate.sh mode change 100644 => 100755 plugins/azure-skills/skills/azure-diagnostics/scripts/aks-baseline.sh mode change 100644 => 100755 plugins/azure-skills/skills/azure-prepare/references/services/sql-database/scripts/grant-sql-access.sh mode change 100644 => 100755 plugins/azure-skills/skills/azure-quotas/scripts/check-quota.sh mode change 100644 => 100755 plugins/azure-skills/skills/azure-validate/references/recipes/azd/scripts/set-aspire-aca-env.sh mode change 100644 => 100755 plugins/azure-skills/skills/azure-validate/references/scripts/scan-aspire-functions-secrets.sh mode change 100644 => 100755 plugins/azure-skills/skills/azure-validate/references/scripts/workflow.sh mode change 100644 => 100755 plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/check-copilot-app-entry.sh mode change 100644 => 100755 plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/resolve-project-id.sh mode change 100644 => 100755 plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/verify-environment.sh mode change 100644 => 100755 plugins/azure-skills/skills/microsoft-foundry/foundry-agent/toolbox/scripts/get-catalog-inputs.sh mode change 100644 => 100755 plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/capacity/scripts/discover_and_rank.sh mode change 100644 => 100755 plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/capacity/scripts/query_capacity.sh mode change 100644 => 100755 plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/scripts/generate_deployment_url.sh mode change 100644 => 100755 plugins/azure-skills/skills/microsoft-foundry/scripts/check-and-setup-dependencies.sh create mode 100644 scripts/src/check-shell-script-permissions.ts diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 893f527ef..02f86dd8f 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -182,6 +182,7 @@ Some skills ship helper scripts (under a skill's `scripts/` or `references/**/sc ### Bash Scripts - **Target Bash 3.2** (macOS default) — do not assume Bash 4+. Avoid `declare -A` (associative arrays), `mapfile`, and similar. Use portable alternatives like `while IFS= read -r` loops and small `grep`/`sed` helpers. Use `#!/usr/bin/env bash`. +- **Mark every shebang-bearing `.sh` script executable in Git** with `git update-index --chmod=+x `; verify the mode with `git ls-files --stage`. - **Never use `eval`** to run a command string (injection risk + brittle quoting). Pass the command as arguments and invoke via `"$@"`, or pass a function name. - **With `set -e`, capture command output via command substitution** (`OUT=$(cmd ...)`), not process substitution (`done < <(cmd ...)`), so a failing command reliably aborts instead of producing a misleading downstream error. - **Use fixed-string grep (`grep -F`/`-Fq`) for literal matches** and handle grep's read-error exit code (`2`) explicitly — don't let it be treated as "no match". @@ -215,6 +216,7 @@ PRs against `main` must pass these checks — run the corresponding local comman | Token Analysis | Token counts and limits for markdown files | `npm run tokens check` | | Skill Structure | Frontmatter, `tests/skills.json` sync, markdown references | `npm run build && cd scripts && npm run frontmatter && npm run references` | | Plugin Version Check | `plugin.json` versions remain `0.0.0-placeholder` | Ensure you never edit version fields | +| Shell Script Permissions | Tracked shebang-bearing `.sh` files have executable Git mode | `npm run check:shell-scripts` | | Skill Tests | Unit and trigger tests for changed skills | `cd tests && npm test` | ## Commit and PR Conventions diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 685e7a5d4..dd7a75123 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -48,6 +48,21 @@ jobs: } } + shell-script-permissions: + name: Shell Script Permissions + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + with: + fetch-depth: 0 + + - name: Validate shebang shell scripts are executable + run: npm run check:shell-scripts + eslint: name: ESLint runs-on: ubuntu-latest diff --git a/package.json b/package.json index 3537930d9..ce63a4cdb 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "description": "GitHub Copilot plugin for Azure", "scripts": { "build": "gulp", + "check:shell-scripts": "cd scripts && npm run checkShellScriptPermissions", "tokens": "cd scripts && npm run tokens --", "verify-local": "echo 'Removed: use npm run build + copilot --plugin-dir ./output instead' && exit 1", "test": "cd scripts && npm test", diff --git a/plugins/azure-skills/skills/azure-app-onboard/scaffold/scripts/scaffold-conformance.sh b/plugins/azure-skills/skills/azure-app-onboard/scaffold/scripts/scaffold-conformance.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/azure-deploy/references/recipes/azd/scripts/apply-migrations.sh b/plugins/azure-skills/skills/azure-deploy/references/recipes/azd/scripts/apply-migrations.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/azure-deploy/references/recipes/azd/scripts/grant-and-migrate.sh b/plugins/azure-skills/skills/azure-deploy/references/recipes/azd/scripts/grant-and-migrate.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/azure-diagnostics/scripts/aks-baseline.sh b/plugins/azure-skills/skills/azure-diagnostics/scripts/aks-baseline.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/azure-prepare/references/services/sql-database/scripts/grant-sql-access.sh b/plugins/azure-skills/skills/azure-prepare/references/services/sql-database/scripts/grant-sql-access.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/azure-quotas/scripts/check-quota.sh b/plugins/azure-skills/skills/azure-quotas/scripts/check-quota.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/azure-validate/references/recipes/azd/scripts/set-aspire-aca-env.sh b/plugins/azure-skills/skills/azure-validate/references/recipes/azd/scripts/set-aspire-aca-env.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/azure-validate/references/scripts/scan-aspire-functions-secrets.sh b/plugins/azure-skills/skills/azure-validate/references/scripts/scan-aspire-functions-secrets.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/azure-validate/references/scripts/workflow.sh b/plugins/azure-skills/skills/azure-validate/references/scripts/workflow.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/check-copilot-app-entry.sh b/plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/check-copilot-app-entry.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/resolve-project-id.sh b/plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/resolve-project-id.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/verify-environment.sh b/plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/verify-environment.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/microsoft-foundry/foundry-agent/toolbox/scripts/get-catalog-inputs.sh b/plugins/azure-skills/skills/microsoft-foundry/foundry-agent/toolbox/scripts/get-catalog-inputs.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/capacity/scripts/discover_and_rank.sh b/plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/capacity/scripts/discover_and_rank.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/capacity/scripts/query_capacity.sh b/plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/capacity/scripts/query_capacity.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/scripts/generate_deployment_url.sh b/plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/scripts/generate_deployment_url.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/microsoft-foundry/scripts/check-and-setup-dependencies.sh b/plugins/azure-skills/skills/microsoft-foundry/scripts/check-and-setup-dependencies.sh old mode 100644 new mode 100755 diff --git a/scripts/package.json b/scripts/package.json index dfbfe581a..eadb39950 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -6,6 +6,7 @@ "scripts": { "build": "tsc", "checkCopilotCliCharBudget": "node --import tsx src/copilot-cli-char-budget.ts", + "checkShellScriptPermissions": "node --import tsx src/check-shell-script-permissions.ts", "checkPluginVersionPr": "node --import tsx src/check-plugin-version-pr.ts", "verifyBuildOutputVersions": "node --import tsx src/verify-build-output-versions.ts", "tokens": "node --import tsx src/tokens/cli.ts", diff --git a/scripts/src/check-shell-script-permissions.ts b/scripts/src/check-shell-script-permissions.ts new file mode 100644 index 000000000..dd90d9e00 --- /dev/null +++ b/scripts/src/check-shell-script-permissions.ts @@ -0,0 +1,49 @@ +import { execFileSync } from "node:child_process"; +import { readFileSync } from "node:fs"; +import { join } from "node:path"; + +/** Runs a Git command and returns its text output. */ +function runGit(args: string[]): string { + return execFileSync("git", args, { encoding: "utf8" }); +} + +/** Verifies tracked shebang-bearing shell scripts have executable Git modes. */ +function checkShellScriptPermissions(): boolean { + const repositoryRoot = runGit(["rev-parse", "--show-toplevel"]).trim(); + const entries = runGit(["ls-files", "--stage", "-z", "--", "*.sh"]) + .split("\0") + .filter(Boolean); + const invalidFiles: string[] = []; + + for (const entry of entries) { + const separatorIndex = entry.indexOf("\t"); + if (separatorIndex < 0) { + throw new Error(`Unexpected git ls-files output: ${entry}`); + } + + const metadata = entry.slice(0, separatorIndex).split(" "); + const file = entry.slice(separatorIndex + 1); + const firstLine = readFileSync(join(repositoryRoot, file), "utf8").split(/\r?\n/, 1)[0]; + + if (firstLine.startsWith("#!") && metadata[0] !== "100755") { + invalidFiles.push(file); + } + } + + if (invalidFiles.length === 0) { + console.log("All tracked shebang-bearing .sh files are executable."); + return true; + } + + console.error("The following tracked shebang-bearing .sh files are not executable:"); + for (const file of invalidFiles) { + console.error(` ${file}`); + } + console.error("Run: git update-index --chmod=+x "); + return false; +} + +const valid = checkShellScriptPermissions(); +process.exitCode = valid ? 0 : 1; + +export { checkShellScriptPermissions }; From 511adce726572f52e6bc036f87173e91a77239c8 Mon Sep 17 00:00:00 2001 From: "Tom Meschter (from Dev Box)" Date: Wed, 5 Aug 2026 13:48:25 -0700 Subject: [PATCH 2/7] fix: install dependencies for shell script check Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/pr.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index dd7a75123..1f0ad7e2d 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -60,6 +60,17 @@ jobs: with: fetch-depth: 0 + - name: Setup Node.js + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: "24" + cache: "npm" + cache-dependency-path: scripts/package.json + + - name: Install scripts dependencies + working-directory: ./scripts + run: npm ci --ignore-scripts + - name: Validate shebang shell scripts are executable run: npm run check:shell-scripts From 700b5771ba43ed9b23f58384ac9a884b68b107c3 Mon Sep 17 00:00:00 2001 From: "Tom Meschter (from Dev Box)" Date: Wed, 5 Aug 2026 14:00:18 -0700 Subject: [PATCH 3/7] fix: scan nested shell scripts Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- scripts/src/check-shell-script-permissions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/src/check-shell-script-permissions.ts b/scripts/src/check-shell-script-permissions.ts index dd90d9e00..a07673148 100644 --- a/scripts/src/check-shell-script-permissions.ts +++ b/scripts/src/check-shell-script-permissions.ts @@ -10,7 +10,7 @@ function runGit(args: string[]): string { /** Verifies tracked shebang-bearing shell scripts have executable Git modes. */ function checkShellScriptPermissions(): boolean { const repositoryRoot = runGit(["rev-parse", "--show-toplevel"]).trim(); - const entries = runGit(["ls-files", "--stage", "-z", "--", "*.sh"]) + const entries = runGit(["ls-files", "--stage", "-z", "--", ":(glob)**/*.sh"]) .split("\0") .filter(Boolean); const invalidFiles: string[] = []; From c9267ec1914e541fb5f48b891b850ab91e17a7e0 Mon Sep 17 00:00:00 2001 From: "Tom Meschter (from Dev Box)" Date: Thu, 6 Aug 2026 10:24:37 -0700 Subject: [PATCH 4/7] chore: split azure app onboard permissions Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../azure-app-onboard/scaffold/scripts/scaffold-conformance.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 plugins/azure-skills/skills/azure-app-onboard/scaffold/scripts/scaffold-conformance.sh diff --git a/plugins/azure-skills/skills/azure-app-onboard/scaffold/scripts/scaffold-conformance.sh b/plugins/azure-skills/skills/azure-app-onboard/scaffold/scripts/scaffold-conformance.sh old mode 100755 new mode 100644 From da4cf6981ffe8f936f4cba5e36221f59c7fd9653 Mon Sep 17 00:00:00 2001 From: "Tom Meschter (from Dev Box)" Date: Thu, 6 Aug 2026 10:31:15 -0700 Subject: [PATCH 5/7] chore: split skill script permissions Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../references/recipes/azd/scripts/apply-migrations.sh | 0 .../references/recipes/azd/scripts/grant-and-migrate.sh | 0 .../azure-skills/skills/azure-diagnostics/scripts/aks-baseline.sh | 0 .../references/services/sql-database/scripts/grant-sql-access.sh | 0 plugins/azure-skills/skills/azure-quotas/scripts/check-quota.sh | 0 .../references/recipes/azd/scripts/set-aspire-aca-env.sh | 0 .../references/recipes/scripts/validate-deployment.sh | 0 .../references/recipes/terraform/scripts/validate-terraform.sh | 0 .../references/scripts/scan-aspire-functions-secrets.sh | 0 .../skills/azure-validate/references/scripts/workflow.sh | 0 .../foundry-agent/create/scripts/check-copilot-app-entry.sh | 0 .../foundry-agent/create/scripts/resolve-project-id.sh | 0 .../foundry-agent/create/scripts/verify-environment.sh | 0 .../foundry-agent/toolbox/scripts/get-catalog-inputs.sh | 0 .../models/deploy-model/capacity/scripts/discover_and_rank.sh | 0 .../models/deploy-model/capacity/scripts/query_capacity.sh | 0 .../models/deploy-model/scripts/generate_deployment_url.sh | 0 .../microsoft-foundry/scripts/check-and-setup-dependencies.sh | 0 .../skills/python-appservice-deploy/scripts/generate-app-name.sh | 0 .../skills/python-appservice-deploy/scripts/retry-az-create.sh | 0 20 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 plugins/azure-skills/skills/azure-deploy/references/recipes/azd/scripts/apply-migrations.sh mode change 100755 => 100644 plugins/azure-skills/skills/azure-deploy/references/recipes/azd/scripts/grant-and-migrate.sh mode change 100755 => 100644 plugins/azure-skills/skills/azure-diagnostics/scripts/aks-baseline.sh mode change 100755 => 100644 plugins/azure-skills/skills/azure-prepare/references/services/sql-database/scripts/grant-sql-access.sh mode change 100755 => 100644 plugins/azure-skills/skills/azure-quotas/scripts/check-quota.sh mode change 100755 => 100644 plugins/azure-skills/skills/azure-validate/references/recipes/azd/scripts/set-aspire-aca-env.sh mode change 100755 => 100644 plugins/azure-skills/skills/azure-validate/references/recipes/scripts/validate-deployment.sh mode change 100755 => 100644 plugins/azure-skills/skills/azure-validate/references/recipes/terraform/scripts/validate-terraform.sh mode change 100755 => 100644 plugins/azure-skills/skills/azure-validate/references/scripts/scan-aspire-functions-secrets.sh mode change 100755 => 100644 plugins/azure-skills/skills/azure-validate/references/scripts/workflow.sh mode change 100755 => 100644 plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/check-copilot-app-entry.sh mode change 100755 => 100644 plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/resolve-project-id.sh mode change 100755 => 100644 plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/verify-environment.sh mode change 100755 => 100644 plugins/azure-skills/skills/microsoft-foundry/foundry-agent/toolbox/scripts/get-catalog-inputs.sh mode change 100755 => 100644 plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/capacity/scripts/discover_and_rank.sh mode change 100755 => 100644 plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/capacity/scripts/query_capacity.sh mode change 100755 => 100644 plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/scripts/generate_deployment_url.sh mode change 100755 => 100644 plugins/azure-skills/skills/microsoft-foundry/scripts/check-and-setup-dependencies.sh mode change 100755 => 100644 plugins/azure-skills/skills/python-appservice-deploy/scripts/generate-app-name.sh mode change 100755 => 100644 plugins/azure-skills/skills/python-appservice-deploy/scripts/retry-az-create.sh diff --git a/plugins/azure-skills/skills/azure-deploy/references/recipes/azd/scripts/apply-migrations.sh b/plugins/azure-skills/skills/azure-deploy/references/recipes/azd/scripts/apply-migrations.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/azure-deploy/references/recipes/azd/scripts/grant-and-migrate.sh b/plugins/azure-skills/skills/azure-deploy/references/recipes/azd/scripts/grant-and-migrate.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/azure-diagnostics/scripts/aks-baseline.sh b/plugins/azure-skills/skills/azure-diagnostics/scripts/aks-baseline.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/azure-prepare/references/services/sql-database/scripts/grant-sql-access.sh b/plugins/azure-skills/skills/azure-prepare/references/services/sql-database/scripts/grant-sql-access.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/azure-quotas/scripts/check-quota.sh b/plugins/azure-skills/skills/azure-quotas/scripts/check-quota.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/azure-validate/references/recipes/azd/scripts/set-aspire-aca-env.sh b/plugins/azure-skills/skills/azure-validate/references/recipes/azd/scripts/set-aspire-aca-env.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/azure-validate/references/recipes/scripts/validate-deployment.sh b/plugins/azure-skills/skills/azure-validate/references/recipes/scripts/validate-deployment.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/azure-validate/references/recipes/terraform/scripts/validate-terraform.sh b/plugins/azure-skills/skills/azure-validate/references/recipes/terraform/scripts/validate-terraform.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/azure-validate/references/scripts/scan-aspire-functions-secrets.sh b/plugins/azure-skills/skills/azure-validate/references/scripts/scan-aspire-functions-secrets.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/azure-validate/references/scripts/workflow.sh b/plugins/azure-skills/skills/azure-validate/references/scripts/workflow.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/check-copilot-app-entry.sh b/plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/check-copilot-app-entry.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/resolve-project-id.sh b/plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/resolve-project-id.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/verify-environment.sh b/plugins/azure-skills/skills/microsoft-foundry/foundry-agent/create/scripts/verify-environment.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/microsoft-foundry/foundry-agent/toolbox/scripts/get-catalog-inputs.sh b/plugins/azure-skills/skills/microsoft-foundry/foundry-agent/toolbox/scripts/get-catalog-inputs.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/capacity/scripts/discover_and_rank.sh b/plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/capacity/scripts/discover_and_rank.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/capacity/scripts/query_capacity.sh b/plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/capacity/scripts/query_capacity.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/scripts/generate_deployment_url.sh b/plugins/azure-skills/skills/microsoft-foundry/models/deploy-model/scripts/generate_deployment_url.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/microsoft-foundry/scripts/check-and-setup-dependencies.sh b/plugins/azure-skills/skills/microsoft-foundry/scripts/check-and-setup-dependencies.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/python-appservice-deploy/scripts/generate-app-name.sh b/plugins/azure-skills/skills/python-appservice-deploy/scripts/generate-app-name.sh old mode 100755 new mode 100644 diff --git a/plugins/azure-skills/skills/python-appservice-deploy/scripts/retry-az-create.sh b/plugins/azure-skills/skills/python-appservice-deploy/scripts/retry-az-create.sh old mode 100755 new mode 100644 From 1535136141ec1381b8be5e9826b412c8ae30e28b Mon Sep 17 00:00:00 2001 From: "Tom Meschter (from Dev Box)" Date: Thu, 6 Aug 2026 10:33:02 -0700 Subject: [PATCH 6/7] chore: preserve existing executable script modes Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../references/recipes/scripts/validate-deployment.sh | 0 .../references/recipes/terraform/scripts/validate-terraform.sh | 0 .../skills/python-appservice-deploy/scripts/generate-app-name.sh | 0 .../skills/python-appservice-deploy/scripts/retry-az-create.sh | 0 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 plugins/azure-skills/skills/azure-validate/references/recipes/scripts/validate-deployment.sh mode change 100644 => 100755 plugins/azure-skills/skills/azure-validate/references/recipes/terraform/scripts/validate-terraform.sh mode change 100644 => 100755 plugins/azure-skills/skills/python-appservice-deploy/scripts/generate-app-name.sh mode change 100644 => 100755 plugins/azure-skills/skills/python-appservice-deploy/scripts/retry-az-create.sh diff --git a/plugins/azure-skills/skills/azure-validate/references/recipes/scripts/validate-deployment.sh b/plugins/azure-skills/skills/azure-validate/references/recipes/scripts/validate-deployment.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/azure-validate/references/recipes/terraform/scripts/validate-terraform.sh b/plugins/azure-skills/skills/azure-validate/references/recipes/terraform/scripts/validate-terraform.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/python-appservice-deploy/scripts/generate-app-name.sh b/plugins/azure-skills/skills/python-appservice-deploy/scripts/generate-app-name.sh old mode 100644 new mode 100755 diff --git a/plugins/azure-skills/skills/python-appservice-deploy/scripts/retry-az-create.sh b/plugins/azure-skills/skills/python-appservice-deploy/scripts/retry-az-create.sh old mode 100644 new mode 100755 From b2c9c58f103e2c75595656393d9fb68292b3c2d0 Mon Sep 17 00:00:00 2001 From: "Tom Meschter (from Dev Box)" Date: Thu, 6 Aug 2026 10:34:01 -0700 Subject: [PATCH 7/7] chore: split shell script guidance Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/copilot-instructions.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 02f86dd8f..893f527ef 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -182,7 +182,6 @@ Some skills ship helper scripts (under a skill's `scripts/` or `references/**/sc ### Bash Scripts - **Target Bash 3.2** (macOS default) — do not assume Bash 4+. Avoid `declare -A` (associative arrays), `mapfile`, and similar. Use portable alternatives like `while IFS= read -r` loops and small `grep`/`sed` helpers. Use `#!/usr/bin/env bash`. -- **Mark every shebang-bearing `.sh` script executable in Git** with `git update-index --chmod=+x `; verify the mode with `git ls-files --stage`. - **Never use `eval`** to run a command string (injection risk + brittle quoting). Pass the command as arguments and invoke via `"$@"`, or pass a function name. - **With `set -e`, capture command output via command substitution** (`OUT=$(cmd ...)`), not process substitution (`done < <(cmd ...)`), so a failing command reliably aborts instead of producing a misleading downstream error. - **Use fixed-string grep (`grep -F`/`-Fq`) for literal matches** and handle grep's read-error exit code (`2`) explicitly — don't let it be treated as "no match". @@ -216,7 +215,6 @@ PRs against `main` must pass these checks — run the corresponding local comman | Token Analysis | Token counts and limits for markdown files | `npm run tokens check` | | Skill Structure | Frontmatter, `tests/skills.json` sync, markdown references | `npm run build && cd scripts && npm run frontmatter && npm run references` | | Plugin Version Check | `plugin.json` versions remain `0.0.0-placeholder` | Ensure you never edit version fields | -| Shell Script Permissions | Tracked shebang-bearing `.sh` files have executable Git mode | `npm run check:shell-scripts` | | Skill Tests | Unit and trigger tests for changed skills | `cd tests && npm test` | ## Commit and PR Conventions