diff --git a/.github/agents/agentic-workflows.agent.md b/.github/agents/agentic-workflows.agent.md index b87715723a..5d07c4497f 100644 --- a/.github/agents/agentic-workflows.agent.md +++ b/.github/agents/agentic-workflows.agent.md @@ -30,7 +30,7 @@ Workflows may optionally include: - Workflow files: `.github/workflows/*.md` and `.github/workflows/**/*.md` - Workflow lock files: `.github/workflows/*.lock.yml` - Shared components: `.github/workflows/shared/*.md` -- Configuration: https://github.com/github/gh-aw/blob/v0.64.4/.github/aw/github-agentic-workflows.md +- Configuration: https://github.com/github/gh-aw/blob/v0.65.0/.github/aw/github-agentic-workflows.md ## Problems This Solves @@ -52,7 +52,7 @@ When you interact with this agent, it will: ### Create New Workflow **Load when**: User wants to create a new workflow from scratch, add automation, or design a workflow that doesn't exist yet -**Prompt file**: https://github.com/github/gh-aw/blob/v0.64.4/.github/aw/create-agentic-workflow.md +**Prompt file**: https://github.com/github/gh-aw/blob/v0.65.0/.github/aw/create-agentic-workflow.md **Use cases**: - "Create a workflow that triages issues" @@ -62,7 +62,7 @@ When you interact with this agent, it will: ### Update Existing Workflow **Load when**: User wants to modify, improve, or refactor an existing workflow -**Prompt file**: https://github.com/github/gh-aw/blob/v0.64.4/.github/aw/update-agentic-workflow.md +**Prompt file**: https://github.com/github/gh-aw/blob/v0.65.0/.github/aw/update-agentic-workflow.md **Use cases**: - "Add web-fetch tool to the issue-classifier workflow" @@ -72,7 +72,7 @@ When you interact with this agent, it will: ### Debug Workflow **Load when**: User needs to investigate, audit, debug, or understand a workflow, troubleshoot issues, analyze logs, or fix errors -**Prompt file**: https://github.com/github/gh-aw/blob/v0.64.4/.github/aw/debug-agentic-workflow.md +**Prompt file**: https://github.com/github/gh-aw/blob/v0.65.0/.github/aw/debug-agentic-workflow.md **Use cases**: - "Why is this workflow failing?" @@ -82,7 +82,7 @@ When you interact with this agent, it will: ### Upgrade Agentic Workflows **Load when**: User wants to upgrade workflows to a new gh-aw version or fix deprecations -**Prompt file**: https://github.com/github/gh-aw/blob/v0.64.4/.github/aw/upgrade-agentic-workflows.md +**Prompt file**: https://github.com/github/gh-aw/blob/v0.65.0/.github/aw/upgrade-agentic-workflows.md **Use cases**: - "Upgrade all workflows to the latest version" @@ -92,7 +92,7 @@ When you interact with this agent, it will: ### Create a Report-Generating Workflow **Load when**: The workflow being created or updated produces reports — recurring status updates, audit summaries, analyses, or any structured output posted as a GitHub issue, discussion, or comment -**Prompt file**: https://github.com/github/gh-aw/blob/v0.64.4/.github/aw/report.md +**Prompt file**: https://github.com/github/gh-aw/blob/v0.65.0/.github/aw/report.md **Use cases**: - "Create a weekly CI health report" @@ -102,7 +102,7 @@ When you interact with this agent, it will: ### Create Shared Agentic Workflow **Load when**: User wants to create a reusable workflow component or wrap an MCP server -**Prompt file**: https://github.com/github/gh-aw/blob/v0.64.4/.github/aw/create-shared-agentic-workflow.md +**Prompt file**: https://github.com/github/gh-aw/blob/v0.65.0/.github/aw/create-shared-agentic-workflow.md **Use cases**: - "Create a shared component for Notion integration" @@ -112,7 +112,7 @@ When you interact with this agent, it will: ### Fix Dependabot PRs **Load when**: User needs to close or fix open Dependabot PRs that update dependencies in generated manifest files (`.github/workflows/package.json`, `.github/workflows/requirements.txt`, `.github/workflows/go.mod`) -**Prompt file**: https://github.com/github/gh-aw/blob/v0.64.4/.github/aw/dependabot.md +**Prompt file**: https://github.com/github/gh-aw/blob/v0.65.0/.github/aw/dependabot.md **Use cases**: - "Fix the open Dependabot PRs for npm dependencies" @@ -122,7 +122,7 @@ When you interact with this agent, it will: ### Analyze Test Coverage **Load when**: The workflow reads, analyzes, or reports test coverage — whether triggered by a PR, a schedule, or a slash command. Always consult this prompt before designing the coverage data strategy. -**Prompt file**: https://github.com/github/gh-aw/blob/v0.64.4/.github/aw/test-coverage.md +**Prompt file**: https://github.com/github/gh-aw/blob/v0.65.0/.github/aw/test-coverage.md **Use cases**: - "Create a workflow that comments coverage on PRs" @@ -169,10 +169,10 @@ gh aw compile --validate ## Important Notes -- Always reference the instructions file at https://github.com/github/gh-aw/blob/v0.64.4/.github/aw/github-agentic-workflows.md for complete documentation +- Always reference the instructions file at https://github.com/github/gh-aw/blob/v0.65.0/.github/aw/github-agentic-workflows.md for complete documentation - Use the MCP tool `agentic-workflows` when running in GitHub Copilot Cloud - Workflows must be compiled to `.lock.yml` files before running in GitHub Actions - **Bash tools are enabled by default** - Don't restrict bash commands unnecessarily since workflows are sandboxed by the AWF - Follow security best practices: minimal permissions, explicit network access, no template injection -- **Network configuration**: Use ecosystem identifiers (`node`, `python`, `go`, etc.) or explicit FQDNs in `network.allowed`. Bare shorthands like `npm` or `pypi` are **not** valid. See https://github.com/github/gh-aw/blob/v0.64.4/.github/aw/network.md for the full list of valid ecosystem identifiers and domain patterns. +- **Network configuration**: Use ecosystem identifiers (`node`, `python`, `go`, etc.) or explicit FQDNs in `network.allowed`. Bare shorthands like `npm` or `pypi` are **not** valid. See https://github.com/github/gh-aw/blob/v0.65.0/.github/aw/network.md for the full list of valid ecosystem identifiers and domain patterns. - **Single-file output**: When creating a workflow, produce exactly **one** workflow `.md` file. Do not create separate documentation files (architecture docs, runbooks, usage guides, etc.). If documentation is needed, add a brief `## Usage` section inside the workflow file itself. diff --git a/.github/aw/actions-lock.json b/.github/aw/actions-lock.json index 004e5d492b..ae6afb5032 100644 --- a/.github/aw/actions-lock.json +++ b/.github/aw/actions-lock.json @@ -5,15 +5,15 @@ "version": "v8", "sha": "ed597411d8f924073f98dfc5c65a23a2325f34cd" }, - "github/gh-aw-actions/setup@v0.64.4": { + "github/gh-aw-actions/setup@v0.65.0": { "repo": "github/gh-aw-actions/setup", - "version": "v0.64.4", - "sha": "7cae8cd356c7905aeda72eb08e1d0b4501310c23" + "version": "v0.65.0", + "sha": "8d14e5b79f1c57d9e76796a60e8dbd44874be574" }, - "github/gh-aw/actions/setup@v0.64.4": { + "github/gh-aw/actions/setup@v0.65.0": { "repo": "github/gh-aw/actions/setup", - "version": "v0.64.4", - "sha": "0b76aaa0e858759e04c1d89599a1041025a24d69" + "version": "v0.65.0", + "sha": "7c193ac298524426fda3c54380651a102cb8813c" } } } diff --git a/.github/skills/fsharp-diagnostics/SKILL.md b/.github/skills/fsharp-diagnostics/SKILL.md index 76b1b2808c..846303abe6 100644 --- a/.github/skills/fsharp-diagnostics/SKILL.md +++ b/.github/skills/fsharp-diagnostics/SKILL.md @@ -1,6 +1,6 @@ --- name: fsharp-diagnostics -description: "After modifying any F# file, use this to get quick parse errors and typecheck warnings+errors. Also finds symbol references and inferred type hints." +description: "Always invoke after editing .fs files. Provides fast parse/typecheck feedback without a full dotnet build. Prefer this over dotnet build for iterative changes. Also finds symbol references and inferred type hints." --- # F# Diagnostics diff --git a/.github/workflows/aw-auto-update.lock.yml b/.github/workflows/aw-auto-update.lock.yml index 02181b3b1c..a19ad13515 100644 --- a/.github/workflows/aw-auto-update.lock.yml +++ b/.github/workflows/aw-auto-update.lock.yml @@ -12,7 +12,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.64.4). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.65.0). DO NOT EDIT. # # To update this file, edit the corresponding .md file and run: # gh aw compile @@ -23,7 +23,7 @@ # Keeps agentic workflows up to date by running `gh aw upgrade` and `gh aw compile` daily. # If changes are detected, pushes them to a long-lived branch and creates or updates a PR. # -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"cee3cbbc17a8d1be9fcf671400323b7e1b15d416cb0ec65fbdb6f441e0e9a1a9","compiler_version":"v0.64.4","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"cee3cbbc17a8d1be9fcf671400323b7e1b15d416cb0ec65fbdb6f441e0e9a1a9","compiler_version":"v0.65.0","strict":true,"agent_id":"copilot"} name: "Agentic Workflow Auto-Update" "on": @@ -58,7 +58,7 @@ jobs: secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Generate agentic run info @@ -69,7 +69,7 @@ jobs: GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'auto' }} GH_AW_INFO_VERSION: "latest" GH_AW_INFO_AGENT_VERSION: "latest" - GH_AW_INFO_CLI_VERSION: "v0.64.4" + GH_AW_INFO_CLI_VERSION: "v0.65.0" GH_AW_INFO_WORKFLOW_NAME: "Agentic Workflow Auto-Update" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" @@ -111,6 +111,16 @@ jobs: setupGlobals(core, github, context, exec, io); const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); await main(); + - name: Check compile-agentic version + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + env: + GH_AW_COMPILED_VERSION: "v0.65.0" + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + await main(); - name: Create prompt with built-in context env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt @@ -177,8 +187,6 @@ jobs: cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" cat << 'GH_AW_PROMPT_129f48edee93c656_EOF' - GH_AW_PROMPT_129f48edee93c656_EOF - cat << 'GH_AW_PROMPT_129f48edee93c656_EOF' {{#runtime-import .github/workflows/aw-auto-update.md}} GH_AW_PROMPT_129f48edee93c656_EOF } > "$GH_AW_PROMPT" @@ -267,7 +275,7 @@ jobs: output_types: ${{ steps.collect_output.outputs.output_types }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Set runtime paths @@ -321,6 +329,7 @@ jobs: id: parse-guard-vars env: GH_AW_BLOCKED_USERS_VAR: ${{ vars.GH_AW_GITHUB_BLOCKED_USERS || '' }} + GH_AW_TRUSTED_USERS_VAR: ${{ vars.GH_AW_GITHUB_TRUSTED_USERS || '' }} GH_AW_APPROVAL_LABELS_VAR: ${{ vars.GH_AW_GITHUB_APPROVAL_LABELS || '' }} run: bash ${RUNNER_TEMP}/gh-aw/actions/parse_guard_list.sh - name: Download container images @@ -544,7 +553,8 @@ jobs: "approval-labels": ${{ steps.parse-guard-vars.outputs.approval_labels }}, "blocked-users": ${{ steps.parse-guard-vars.outputs.blocked_users }}, "min-integrity": "none", - "repos": "all" + "repos": "all", + "trusted-users": ${{ steps.parse-guard-vars.outputs.trusted_users }} } } }, @@ -597,7 +607,7 @@ jobs: GH_AW_PHASE: agent GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_VERSION: v0.64.4 + GH_AW_VERSION: v0.65.0 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_HEAD_REF: ${{ github.head_ref }} @@ -785,7 +795,7 @@ jobs: total_count: ${{ steps.missing_tool.outputs.total_count }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Download agent output artifact @@ -898,7 +908,7 @@ jobs: detection_success: ${{ steps.detection_conclusion.outputs.success }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Download agent output artifact @@ -991,7 +1001,7 @@ jobs: COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_VERSION: v0.64.4 + GH_AW_VERSION: v0.65.0 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_HEAD_REF: ${{ github.head_ref }} @@ -1055,7 +1065,7 @@ jobs: push_commit_url: ${{ steps.process_safe_outputs.outputs.push_commit_url }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Download agent output artifact diff --git a/.github/workflows/regression-pr-shepherd.lock.yml b/.github/workflows/regression-pr-shepherd.lock.yml index 1466fac83c..e7b434376a 100644 --- a/.github/workflows/regression-pr-shepherd.lock.yml +++ b/.github/workflows/regression-pr-shepherd.lock.yml @@ -12,7 +12,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.64.4). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.65.0). DO NOT EDIT. # # To update this file, edit the corresponding .md file and run: # gh aw compile @@ -25,7 +25,7 @@ # actually proves the bug still exists. # Runs 6 times per day. # -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"83657c4bc08a81d82e8fbf14c41ebe0e941dcd4c5984fe0b5501193e58921dd6","compiler_version":"v0.64.4","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"83657c4bc08a81d82e8fbf14c41ebe0e941dcd4c5984fe0b5501193e58921dd6","compiler_version":"v0.65.0","strict":true,"agent_id":"copilot"} name: "Regression PR Shepherd" "on": @@ -60,7 +60,7 @@ jobs: secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Generate agentic run info @@ -71,7 +71,7 @@ jobs: GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'auto' }} GH_AW_INFO_VERSION: "latest" GH_AW_INFO_AGENT_VERSION: "latest" - GH_AW_INFO_CLI_VERSION: "v0.64.4" + GH_AW_INFO_CLI_VERSION: "v0.65.0" GH_AW_INFO_WORKFLOW_NAME: "Regression PR Shepherd" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" @@ -113,6 +113,16 @@ jobs: setupGlobals(core, github, context, exec, io); const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); await main(); + - name: Check compile-agentic version + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + env: + GH_AW_COMPILED_VERSION: "v0.65.0" + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + await main(); - name: Create prompt with built-in context env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt @@ -177,8 +187,6 @@ jobs: cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" cat << 'GH_AW_PROMPT_25b0cc8c3d11c822_EOF' - GH_AW_PROMPT_25b0cc8c3d11c822_EOF - cat << 'GH_AW_PROMPT_25b0cc8c3d11c822_EOF' {{#runtime-import .github/workflows/regression-pr-shepherd.md}} GH_AW_PROMPT_25b0cc8c3d11c822_EOF } > "$GH_AW_PROMPT" @@ -279,7 +287,7 @@ jobs: output_types: ${{ steps.collect_output.outputs.output_types }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Set runtime paths @@ -342,6 +350,7 @@ jobs: id: parse-guard-vars env: GH_AW_BLOCKED_USERS_VAR: ${{ vars.GH_AW_GITHUB_BLOCKED_USERS || '' }} + GH_AW_TRUSTED_USERS_VAR: ${{ vars.GH_AW_GITHUB_TRUSTED_USERS || '' }} GH_AW_APPROVAL_LABELS_VAR: ${{ vars.GH_AW_GITHUB_APPROVAL_LABELS || '' }} run: bash ${RUNNER_TEMP}/gh-aw/actions/parse_guard_list.sh - name: Download container images @@ -567,7 +576,8 @@ jobs: "approval-labels": ${{ steps.parse-guard-vars.outputs.approval_labels }}, "blocked-users": ${{ steps.parse-guard-vars.outputs.blocked_users }}, "min-integrity": "none", - "repos": "all" + "repos": "all", + "trusted-users": ${{ steps.parse-guard-vars.outputs.trusted_users }} } } }, @@ -620,7 +630,7 @@ jobs: GH_AW_PHASE: agent GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_VERSION: v0.64.4 + GH_AW_VERSION: v0.65.0 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_HEAD_REF: ${{ github.head_ref }} @@ -819,7 +829,7 @@ jobs: total_count: ${{ steps.missing_tool.outputs.total_count }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Download agent output artifact @@ -922,7 +932,7 @@ jobs: detection_success: ${{ steps.detection_conclusion.outputs.success }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Download agent output artifact @@ -1015,7 +1025,7 @@ jobs: COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_VERSION: v0.64.4 + GH_AW_VERSION: v0.65.0 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_HEAD_REF: ${{ github.head_ref }} @@ -1065,7 +1075,7 @@ jobs: validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Checkout repository @@ -1146,7 +1156,7 @@ jobs: push_commit_url: ${{ steps.process_safe_outputs.outputs.push_commit_url }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Download agent output artifact diff --git a/.github/workflows/regression-pr-shepherd.md b/.github/workflows/regression-pr-shepherd.md index 1585ed6280..7f10309d57 100644 --- a/.github/workflows/regression-pr-shepherd.md +++ b/.github/workflows/regression-pr-shepherd.md @@ -61,10 +61,14 @@ List all open PRs with the `AI-Issue-Regression-PR` label: gh pr list --label "AI-Issue-Regression-PR" --state open --json number,title,headRefName,updatedAt ``` +**Process at most 3 PRs per run.** Prioritize PRs that have unaddressed review feedback (Category A) or CI failures (Category B) over healthy PRs (Category C). If more than 3 PRs need work, the next scheduled run will pick up the rest. + For each PR, determine which category it falls into (check in this order): ### Step 2 — Categorize each PR +First, do a quick triage pass: check the mergeable state and latest check-run status for each PR before reading any diffs or logs. This avoids loading unnecessary context for Category C (healthy) PRs. Skip healthy PRs immediately. + **Category A: Has unaddressed review feedback** Check for review comments posted since the last Repo Assist comment on this PR (look for the `🤖` marker). If new human review comments exist: diff --git a/.github/workflows/repo-assist.lock.yml b/.github/workflows/repo-assist.lock.yml index 9086ea4225..cb19658215 100644 --- a/.github/workflows/repo-assist.lock.yml +++ b/.github/workflows/repo-assist.lock.yml @@ -12,7 +12,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.64.4). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.65.0). DO NOT EDIT. # # To update this file, edit githubnext/agentics/workflows/repo-assist.md@9135cdfde26838a01779aa966628308404ec1f02 and run: # gh aw compile @@ -35,7 +35,7 @@ # # Source: githubnext/agentics/workflows/repo-assist.md@9135cdfde26838a01779aa966628308404ec1f02 # -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"b09f3395fc1a506af9e7289541ecf17a0b192c57e9dd7c2d578d1ce750da838f","compiler_version":"v0.64.4","strict":true,"agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"b09f3395fc1a506af9e7289541ecf17a0b192c57e9dd7c2d578d1ce750da838f","compiler_version":"v0.65.0","strict":true,"agent_id":"copilot"} name: "Repo Assist" "on": @@ -105,7 +105,7 @@ jobs: title: ${{ steps.sanitized.outputs.title }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Generate agentic run info @@ -116,7 +116,7 @@ jobs: GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'auto' }} GH_AW_INFO_VERSION: "latest" GH_AW_INFO_AGENT_VERSION: "latest" - GH_AW_INFO_CLI_VERSION: "v0.64.4" + GH_AW_INFO_CLI_VERSION: "v0.65.0" GH_AW_INFO_WORKFLOW_NAME: "Repo Assist" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" @@ -171,6 +171,16 @@ jobs: setupGlobals(core, github, context, exec, io); const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); await main(); + - name: Check compile-agentic version + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 + env: + GH_AW_COMPILED_VERSION: "v0.65.0" + with: + script: | + const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + await main(); - name: Compute current body text id: sanitized uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 @@ -263,8 +273,6 @@ jobs: fi cat << 'GH_AW_PROMPT_737e7e7a7b6612d8_EOF' - GH_AW_PROMPT_737e7e7a7b6612d8_EOF - cat << 'GH_AW_PROMPT_737e7e7a7b6612d8_EOF' {{#runtime-import .github/workflows/repo-assist.md}} GH_AW_PROMPT_737e7e7a7b6612d8_EOF } > "$GH_AW_PROMPT" @@ -377,7 +385,7 @@ jobs: output_types: ${{ steps.collect_output.outputs.output_types }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Set runtime paths @@ -440,6 +448,7 @@ jobs: id: parse-guard-vars env: GH_AW_BLOCKED_USERS_VAR: ${{ vars.GH_AW_GITHUB_BLOCKED_USERS || '' }} + GH_AW_TRUSTED_USERS_VAR: ${{ vars.GH_AW_GITHUB_TRUSTED_USERS || '' }} GH_AW_APPROVAL_LABELS_VAR: ${{ vars.GH_AW_GITHUB_APPROVAL_LABELS || '' }} run: bash ${RUNNER_TEMP}/gh-aw/actions/parse_guard_list.sh - name: Download container images @@ -811,7 +820,8 @@ jobs: "approval-labels": ${{ steps.parse-guard-vars.outputs.approval_labels }}, "blocked-users": ${{ steps.parse-guard-vars.outputs.blocked_users }}, "min-integrity": "none", - "repos": "all" + "repos": "all", + "trusted-users": ${{ steps.parse-guard-vars.outputs.trusted_users }} } } }, @@ -864,7 +874,7 @@ jobs: GH_AW_PHASE: agent GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_VERSION: v0.64.4 + GH_AW_VERSION: v0.65.0 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_HEAD_REF: ${{ github.head_ref }} @@ -1064,7 +1074,7 @@ jobs: total_count: ${{ steps.missing_tool.outputs.total_count }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Download agent output artifact @@ -1209,7 +1219,7 @@ jobs: detection_success: ${{ steps.detection_conclusion.outputs.success }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Download agent output artifact @@ -1302,7 +1312,7 @@ jobs: COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_VERSION: v0.64.4 + GH_AW_VERSION: v0.65.0 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_HEAD_REF: ${{ github.head_ref }} @@ -1343,7 +1353,7 @@ jobs: matched_command: ${{ steps.check_command_position.outputs.matched_command }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Check team membership for command workflow @@ -1387,7 +1397,7 @@ jobs: validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Checkout repository @@ -1474,7 +1484,7 @@ jobs: push_commit_url: ${{ steps.process_safe_outputs.outputs.push_commit_url }} steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@7cae8cd356c7905aeda72eb08e1d0b4501310c23 # v0.64.4 + uses: github/gh-aw-actions/setup@8d14e5b79f1c57d9e76796a60e8dbd44874be574 # v0.65.0 with: destination: ${{ runner.temp }}/gh-aw/actions - name: Download agent output artifact diff --git a/src/Compiler/Checking/QuotationTranslator.fs b/src/Compiler/Checking/QuotationTranslator.fs index ed37c3ba46..f861a8ee26 100644 --- a/src/Compiler/Checking/QuotationTranslator.fs +++ b/src/Compiler/Checking/QuotationTranslator.fs @@ -574,6 +574,14 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : Exp let eq = mkCallEqualsOperator g m ty arg1 arg2 ConvExpr cenv env eq + // Handle non-null test pattern (arg <> null), generated by pattern matching optimizations + // e.g. empty string matching: match x with "" -> ... | _ -> ... + | TOp.ILAsm ([ AI_ldnull; AI_cgt_un ], _), _, [arg1] -> + let ty = tyOfExpr g arg1 + let neq = mkCallNotEqualsOperator g m ty arg1 (Expr.Const (Const.Zero, m, ty)) + let env = { env with suppressWitnesses = true } + ConvExpr cenv env neq + | TOp.ILAsm ([ I_throw ], _), _, [arg1] -> let raiseExpr = mkCallRaise g m (tyOfExpr g expr) arg1 ConvExpr cenv env raiseExpr diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ExpressionQuotations/Regressions.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ExpressionQuotations/Regressions.fs index ae2f1b663a..c80190c85d 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ExpressionQuotations/Regressions.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ExpressionQuotations/Regressions.fs @@ -216,3 +216,69 @@ module Regressions = // E_QuoteDynamic01 test removed - the FS0458 error for member constraint calls in quotations // was specific to F# 4.6 behavior. Modern F# (8.0+) handles this case differently and the code // now compiles successfully. This was a version-gate test, not a behavior test. + + // ======================================== + // Inline regression tests + // ======================================== + + // https://github.com/dotnet/fsharp/issues/18706 + [] + let ``Empty string pattern match in quotation should compile`` () = + FSharp """ +module Test +let q = <@ fun (x: string) -> match x with "" -> "empty" | _ -> "other" @> + """ + |> asLibrary + |> typecheck + |> shouldSucceed + + // https://github.com/dotnet/fsharp/issues/18706 + [] + let ``Empty string pattern match in quotation with multiple cases should compile`` () = + FSharp """ +module Test +let q = <@ fun (x: string) -> match x with "" -> "empty" | "hello" -> "hello" | _ -> "other" @> + """ + |> asLibrary + |> typecheck + |> shouldSucceed + + // https://github.com/dotnet/fsharp/issues/18706 + [] + let ``Non-empty string pattern match in quotation should still compile`` () = + FSharp """ +module Test +let q = <@ fun (x: string) -> match x with "hello" -> "match" | _ -> "other" @> + """ + |> asLibrary + |> typecheck + |> shouldSucceed + + // https://github.com/dotnet/fsharp/issues/18706 + [] + let ``Empty string pattern match in quotation produces correct runtime result`` () = + FSharp """ +open Microsoft.FSharp.Quotations +open Microsoft.FSharp.Quotations.Patterns + +let q = <@ fun (x: string) -> match x with "" -> "empty" | _ -> "other" @> + +// Verify the quotation has the expected shape: a Lambda containing an IfThenElse +match q with +| Lambda(_, IfThenElse _) -> () +| _ -> failwithf "Unexpected quotation shape: %A" q + """ + |> asExe + |> compileExeAndRun + |> shouldSucceed + + // https://github.com/dotnet/fsharp/issues/18706 + [] + let ``Empty string pattern match in quotation with outer variable should compile`` () = + FSharp """ +let x = "test" +let q = <@@ match x with "" -> "empty" | _ -> "other" @@> + """ + |> asExe + |> compileExeAndRun + |> shouldSucceed diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index 42eb6c29fb..5fe0868524 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -1831,3 +1831,29 @@ let _x3 = curryN f3 1 2 3 FSharp "module T\nopen CsLib\nlet _ = IP.Get()" |> asExe |> withOptions iwsamWarnings |> withReferences [csLib] |> compileAndRun |> shouldSucceed + // https://github.com/dotnet/fsharp/issues/15987 + [] + let ``Issue 15987 - SRTP overload resolution returns correct value for typed argument`` () = + FSharp """ +module Test + +type A = A with + static member ($) (A, a: float ) = 0.0 + static member ($) (A, a: decimal) = 0M + static member ($) (A, a: 't ) = 0 + +let inline call x = ($) A x + +// Verify correct overload is selected: float argument should use the float overload +let resultFloat: float = call 42.0 +let resultDecimal: decimal = call 42M +let resultInt: int = call 42 + +if resultFloat <> 0.0 then failwith $"Expected 0.0 but got {resultFloat}" +if resultDecimal <> 0M then failwith $"Expected 0M but got {resultDecimal}" +if resultInt <> 0 then failwith $"Expected 0 but got {resultInt}" +""" + |> asExe + |> compileAndRun + |> shouldSucceed + diff --git a/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs b/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs index 5f424466c2..9e04bc75df 100644 --- a/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs +++ b/tests/FSharp.Compiler.ComponentTests/ConstraintSolver/MemberConstraints.fs @@ -150,6 +150,23 @@ type UnionOfUnions<'T> = |> typecheck |> shouldSucceed + // https://github.com/dotnet/fsharp/issues/9878 + [] + let ``Issue 9878 - SRTP with phantom type parameter should compile`` () = + FSharp + """ +type DuCaseName<'T> = + static member ToCaseName<'t, 'u>(value: 't) = failwith "delayed resolution" + static member ToCaseName(value: 'T) = + match FSharp.Reflection.FSharpValue.GetUnionFields(value, typeof<'T>) with case, _ -> case.Name + static member inline Invoke(value: 'a) = + let inline call (other: ^M, value: ^I) = ((^M or ^I) : (static member ToCaseName: ^I -> string) value) + call (Unchecked.defaultof>, value) + """ + |> asLibrary + |> typecheck + |> shouldSucceed + // https://github.com/dotnet/fsharp/issues/9382 [] let ``Issue 9382 - SRTP stress test with matrix inverse should compile`` () = diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/DiagnosticRegressionTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/DiagnosticRegressionTests.fs index c8517a57e6..36e258e4dd 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/DiagnosticRegressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/DiagnosticRegressionTests.fs @@ -3,6 +3,23 @@ module ErrorMessages.DiagnosticRegressionTests open Xunit open FSharp.Test.Compiler +// https://github.com/dotnet/fsharp/issues/6715 +[] +let ``Issue 6715 - land is a valid identifier after ML compat removal`` () = + FSharp + """ +let land = 3 +let lor = 4 +let lxor = 5 +let lsl = 6 +let lsr = 7 +let asr = 8 +let sum = land + lor + lxor + lsl + lsr + asr + """ + |> asLibrary + |> typecheck + |> shouldSucceed + // https://github.com/dotnet/fsharp/issues/15655 [] let ``Issue 15655 - error codes 999 and 3217 are distinct`` () = @@ -34,6 +51,23 @@ type Vehicle() = class end (Error 267, Line 3, Col 7, Line 3, Col 29, "This is not a valid constant expression or custom attribute value") ] +// https://github.com/dotnet/fsharp/issues/7177 +[] +let ``Issue 7177 - never matched warning FS0026 is emitted when active pattern precedes wildcard rules`` () = + FSharp """ +let (|AP|_|) (x: obj) = Some() + +let _ = + match obj() with + | AP _ -> () + | _ -> () + | _ -> () + """ + |> asLibrary + |> typecheck + |> shouldFail + |> withWarningCode 26 + // https://github.com/dotnet/fsharp/issues/16410 [] let ``Issue 16410 - no spurious FS3570 warning with KeyValue active pattern`` () = diff --git a/tests/FSharp.Compiler.ComponentTests/InteractiveSession/Misc.fs b/tests/FSharp.Compiler.ComponentTests/InteractiveSession/Misc.fs index 97d0dcd865..74298498db 100644 --- a/tests/FSharp.Compiler.ComponentTests/InteractiveSession/Misc.fs +++ b/tests/FSharp.Compiler.ComponentTests/InteractiveSession/Misc.fs @@ -1997,9 +1997,13 @@ if toEnd <> [| 3; 4; 5 |] then exit 1 let name = "World" let count = 42 let greeting = $"Hello, {name}! Count: {count}" +printfn "%s" greeting if greeting <> "Hello, World! Count: 42" then exit 1 +System.Globalization.CultureInfo.CurrentCulture <- System.Globalization.CultureInfo.InvariantCulture + let formatted = $"Pi is approximately {System.Math.PI:F2}" +printfn "%s" formatted if not (formatted.Contains("3.14")) then exit 1 () """ diff --git a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs index 378879bbfc..13652e42ef 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs @@ -2323,3 +2323,22 @@ let result = query { for x in data1 do join (y, name) in data2 on (x = y); selec |> shouldFail |> withSingleDiagnostic (Warning 1182, Line line1, Col col1, Line line2, Col col2, msg) |> ignore + + // https://github.com/dotnet/fsharp/issues/19456 + [] + let ``Issue 19456 - let bang nested in plain let binding inside task CE should raise FS0750`` () = + FSharp """ +open System.Threading.Tasks + +let y() = + task { + let a = + let! b = Task.FromResult([| "hello" |]) + b + return a + } + """ + |> asLibrary + |> typecheck + |> shouldFail + |> withErrorCode 750 diff --git a/tests/FSharp.Compiler.ComponentTests/Language/RegressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/RegressionTests.fs index f035c28b51..3b7d1a2b3a 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/RegressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/RegressionTests.fs @@ -68,3 +68,17 @@ let x = 15 |> asLibrary |> typecheck |> shouldSucceed + + // https://github.com/dotnet/fsharp/issues/16007 + [] + let ``Issue 16007 - SRTP ctor constraint should not cause value restriction error`` () = + FSharp """ +type T() = class end +let dosmth (a: T) = System.Console.WriteLine(a.ToString()) +let inline NEW () = (^a : (new : unit -> ^a) ()) +let x = NEW () +dosmth x + """ + |> asLibrary + |> typecheck + |> shouldSucceed diff --git a/tests/FSharp.Compiler.ComponentTests/Miscellaneous/FsharpSuiteMigrated.fs b/tests/FSharp.Compiler.ComponentTests/Miscellaneous/FsharpSuiteMigrated.fs index 0b6e230a27..e0cfdff2ff 100644 --- a/tests/FSharp.Compiler.ComponentTests/Miscellaneous/FsharpSuiteMigrated.fs +++ b/tests/FSharp.Compiler.ComponentTests/Miscellaneous/FsharpSuiteMigrated.fs @@ -23,7 +23,7 @@ module ScriptRunner = let private getOrCreateEngine(args,version) sessionIsolation = match sessionIsolation with | ScriptSessionIsolation.Isolated -> - new FSharpScript(args, true, version) + getIsolatedSessionForEval args version | ScriptSessionIsolation.Shared -> getSessionForEval args version diff --git a/tests/FSharp.Compiler.ComponentTests/Scripting/TypeCheckOnlyTests.fs b/tests/FSharp.Compiler.ComponentTests/Scripting/TypeCheckOnlyTests.fs index b6717ecd5b..9a3279f710 100644 --- a/tests/FSharp.Compiler.ComponentTests/Scripting/TypeCheckOnlyTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Scripting/TypeCheckOnlyTests.fs @@ -110,3 +110,18 @@ let ``typecheck-only flag prevents execution with #load``() = |> verifyNotInOutput "Domain.fsx output" |> verifyNotInOutput "A.fsx output" |> ignore) + +// https://github.com/dotnet/fsharp/issues/15070 +[] +let ``Issue 15070 - hash-load with dot-slash prefix does not produce FS1141`` () = + // Before the fix, #load "./path" produced FS1141 "Identifiers followed by '!' are reserved for future use" + // After the fix, the parser accepts "./path" and reports a file-not-found error instead. + withTempDirectory (fun tempDir -> + let mainContent = "#load \"./non-existent-subfolder/some-script.fsx\"" + let mainPath = writeScript tempDir "main.fsx" mainContent + + FsxFromPath mainPath + |> runFsi + |> shouldFail + |> withStdErrContains "Unable to find the file" + |> ignore) diff --git a/tests/FSharp.Compiler.Service.Tests/Symbols.fs b/tests/FSharp.Compiler.Service.Tests/Symbols.fs index f862a46e5e..3f4d4fcdbd 100644 --- a/tests/FSharp.Compiler.Service.Tests/Symbols.fs +++ b/tests/FSharp.Compiler.Service.Tests/Symbols.fs @@ -842,6 +842,38 @@ type T() = let param = mfv.CurriedParameterGroups[0][0] param.Name.Value |> shouldEqual "x" + // https://github.com/dotnet/fsharp/issues/16056 + [] + let ``Auto property DeclarationLocation points to property name, not get accessor`` () = + let _, checkResults = + getParseAndCheckResults """ +module Module + +type T() = + member val Prop : int = 1 with get, set + +let _ = T().Prop +""" + let propUsageOpt = + checkResults.GetAllUsesOfAllSymbolsInFile() + |> Seq.tryFind (fun su -> + match su.Symbol with + | :? FSharpMemberOrFunctionOrValue as mfv -> + mfv.IsProperty && mfv.LogicalName = "Prop" && not su.IsFromDefinition + | _ -> false) + + match propUsageOpt with + | None -> failwith "Expected to find Prop usage symbol" + | Some symbolUse -> + match symbolUse.Symbol with + | :? FSharpMemberOrFunctionOrValue as mfv -> + let loc = mfv.DeclarationLocation + // " member val Prop" - 'P' in 'Prop' starts at column 15 (0-indexed) + // Should NOT point to `get` accessor (which is at column 35) + Assert.Equal(5, loc.StartLine) + Assert.Equal(15, loc.StartColumn) + | _ -> failwith "Expected FSharpMemberOrFunctionOrValue" + module GetValSignatureText = let private assertSignature (expected:string) source (lineNumber, column, line, identifier) = let _, checkResults = getParseAndCheckResults source diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index afbe687012..af1f36ca80 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -1133,13 +1133,11 @@ module rec Compiler = let outputWritten, errorsWritten = capture.OutText, capture.ErrorText processScriptResults fs result outputWritten errorsWritten - let scriptingShim = Path.Combine(__SOURCE_DIRECTORY__,"ScriptingShims.fsx") let private evalScriptFromDisk (fs: FSharpCompilationSource) (script:FSharpScript) : CompilationResult = let fileNames = (fs.Source :: fs.AdditionalSources) |> List.map (fun x -> x.GetSourceFileName) - |> List.insertAt 0 scriptingShim |> List.map (sprintf " @\"%s\"") |> String.Concat @@ -1158,13 +1156,21 @@ module rec Compiler = let internal sessionCache = Collections.Concurrent.ConcurrentDictionary * LangVersion, FSharpScript>() + + let internal createSessionWithShadowedExit args version = + let script = new FSharpScript(additionalArgs=args,quiet=true,langVersion=version) + script.ApplyExitShadowing() + script + + let getIsolatedSessionForEval args version = + createSessionWithShadowedExit args version let getSessionForEval args version = let key = Set args, version match sessionCache.TryGetValue(key) with | true, script -> script | _ -> - let script = new FSharpScript(additionalArgs=args,quiet=true,langVersion=version) + let script = createSessionWithShadowedExit args version sessionCache.TryAdd(key, script) |> ignore script diff --git a/tests/FSharp.Test.Utilities/CompilerAssert.fs b/tests/FSharp.Test.Utilities/CompilerAssert.fs index 1101001e05..7a6315d81e 100644 --- a/tests/FSharp.Test.Utilities/CompilerAssert.fs +++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs @@ -22,6 +22,7 @@ open FSharp.Compiler.BuildGraph open System.Runtime.Loader #endif open FSharp.Test.Utilities +open FSharp.Test.ScriptHelpers open Microsoft.CodeAnalysis open Microsoft.CodeAnalysis.CSharp open Xunit @@ -1011,41 +1012,25 @@ Updated automatically, please check diffs in your pull request, changes must be // Save CurrentUICulture and GraphNode.culture to restore after FSI session // FSI may change these via --preferreduilang option, and the change persists // in the static GraphNode.culture which affects async computations in other tests - let originalUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture - let originalGraphNodeCulture = GraphNode.culture - + let originalUICulture = CultureInfo.CurrentUICulture + let originalGraphNodeCulture = GraphNode.culture try - // Initialize output and input streams - use inStream = new StringReader("") use outStream = new StringWriter() use errStream = new StringWriter() + use script = new FSharpScript(additionalArgs = Array.append [| "--noninteractive" |] options, quiet = false, outWriter = outStream, errWriter = errStream) + script.ApplyExitShadowing() + let result, errors = script.Eval(source) - // Build command line arguments & start FSI session - let argv = [| "C:\\fsi.exe" |] -#if NETCOREAPP - let args = Array.append argv [|"--noninteractive"; "--targetprofile:netcore"|] -#else - let args = Array.append argv [|"--noninteractive"; "--targetprofile:mscorlib"|] -#endif - let allArgs = Array.append args options - - let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration() - use fsiSession = FsiEvaluationSession.Create(fsiConfig, allArgs, inStream, outStream, errStream, collectible = true) - - let ch, errors = fsiSession.EvalInteractionNonThrowing source - - let errorMessages = ResizeArray() - errors - |> Seq.iter (fun error -> errorMessages.Add(error.Message)) + let errorMessages = ResizeArray(errors |> Seq.map _.Message) - match ch with - | Choice2Of2 ex -> errorMessages.Add(ex.Message) + match result with + | Result.Error ex -> errorMessages.Add(ex.Message) | _ -> () errorMessages, string outStream, string errStream finally // Restore CurrentUICulture and GraphNode.culture to prevent culture leaking between tests - System.Threading.Thread.CurrentThread.CurrentUICulture <- originalUICulture + CultureInfo.CurrentUICulture <- originalUICulture GraphNode.culture <- originalGraphNodeCulture static member RunScriptWithOptions options (source: string) (expectedErrorMessages: string list) = diff --git a/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj b/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj index fde44ceb83..cb5f54ad38 100644 --- a/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj +++ b/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj @@ -25,16 +25,15 @@ scriptlib.fsx - + - diff --git a/tests/FSharp.Test.Utilities/ScriptHelpers.fs b/tests/FSharp.Test.Utilities/ScriptHelpers.fs index a0c5b17848..cb2956ab8a 100644 --- a/tests/FSharp.Test.Utilities/ScriptHelpers.fs +++ b/tests/FSharp.Test.Utilities/ScriptHelpers.fs @@ -19,7 +19,7 @@ type LangVersion = | Preview | Latest -type FSharpScript(?additionalArgs: string[], ?quiet: bool, ?langVersion: LangVersion) = +type FSharpScript(?additionalArgs: string[], ?quiet: bool, ?langVersion: LangVersion, ?outWriter: IO.TextWriter, ?errWriter: IO.TextWriter) = let additionalArgs = defaultArg additionalArgs [||] let quiet = defaultArg quiet true @@ -44,13 +44,23 @@ type FSharpScript(?additionalArgs: string[], ?quiet: bool, ?langVersion: LangVer let argv = Array.append baseArgs additionalArgs - let fsi = FsiEvaluationSession.Create (config, argv, TextReader.Null, stdout, stderr) + let outWriter = defaultArg outWriter stdout + let errWriter = defaultArg errWriter stderr + let fsi = FsiEvaluationSession.Create (config, argv, TextReader.Null, outWriter, errWriter) member _.ValueBound = fsi.ValueBound member _.Fsi = fsi - member this.Eval(code: string, ?cancellationToken: CancellationToken, ?desiredCulture: Globalization.CultureInfo) = + member _.ApplyExitShadowing() = + fsi.EvalInteraction """ +let exit (code:int) = + if code = 0 then + () + else failwith $"Script called function 'exit' with code={code}." + """ + + member _.Eval(code: string, ?cancellationToken: CancellationToken, ?desiredCulture: Globalization.CultureInfo) = let originalCulture = Thread.CurrentThread.CurrentCulture let originalUICulture = Thread.CurrentThread.CurrentUICulture Thread.CurrentThread.CurrentCulture <- Option.defaultValue Globalization.CultureInfo.InvariantCulture desiredCulture diff --git a/tests/FSharp.Test.Utilities/ScriptingShims.fsx b/tests/FSharp.Test.Utilities/ScriptingShims.fsx deleted file mode 100644 index be9ce9142c..0000000000 --- a/tests/FSharp.Test.Utilities/ScriptingShims.fsx +++ /dev/null @@ -1,8 +0,0 @@ -namespace global - -[] -module GlobalShims = - let exit (code:int) = - if code = 0 then - () - else failwith $"Script called function 'exit' with code={code}." diff --git a/tests/FSharp.Test.Utilities/TestFramework.fs b/tests/FSharp.Test.Utilities/TestFramework.fs index dcb64909ad..2348b09df8 100644 --- a/tests/FSharp.Test.Utilities/TestFramework.fs +++ b/tests/FSharp.Test.Utilities/TestFramework.fs @@ -60,8 +60,6 @@ let rec copyDirectory (sourceDir: string) (destinationDir: string) (recursive: b [] module Commands = - let gate = obj() - // Execute the process pathToExe passing the arguments: arguments with the working directory: workingDir timeout after timeout milliseconds -1 = wait forever // returns exit code, stdio and stderr as string arrays let executeProcess pathToExe arguments workingDir = diff --git a/tests/fsharp/single-test.fs b/tests/fsharp/single-test.fs index 41f6e03260..e8d2671197 100644 --- a/tests/fsharp/single-test.fs +++ b/tests/fsharp/single-test.fs @@ -9,8 +9,6 @@ open FSharp.Compiler.IO let testConfig = testConfig __SOURCE_DIRECTORY__ -let log = printfn - type Permutation = #if NETCOREAPP | FSC_NETCORE of optimized: bool * buildOnly: bool diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index e834af94ae..330ffe9359 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -27,8 +27,6 @@ let FSI = FSI_NETFX #endif // ^^^^^^^^^^^^ To run these tests in F# Interactive , 'build net40', then send this chunk, then evaluate body of a test ^^^^^^^^^^^^ -let log = printfn - module CoreTests =