diff --git a/.github/workflows/audit-workflows.lock.yml b/.github/workflows/audit-workflows.lock.yml index 613411c356..10fe81b71c 100644 --- a/.github/workflows/audit-workflows.lock.yml +++ b/.github/workflows/audit-workflows.lock.yml @@ -171,7 +171,7 @@ jobs: mkdir -p /tmp/gh-aw/sandbox/agent/logs echo "Created /tmp/gh-aw/agent directory for agentic workflow temporary files" - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: cache: true go-version-file: go.mod @@ -193,7 +193,7 @@ jobs: pip install --user --quiet numpy pandas matplotlib seaborn scipy - if: always() name: Upload charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: trending-charts @@ -201,7 +201,7 @@ jobs: retention-days: 30 - if: always() name: Upload source and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: trending-source-and-data diff --git a/.github/workflows/copilot-pr-nlp-analysis.lock.yml b/.github/workflows/copilot-pr-nlp-analysis.lock.yml index 4976cefe6d..e8122b1dcc 100644 --- a/.github/workflows/copilot-pr-nlp-analysis.lock.yml +++ b/.github/workflows/copilot-pr-nlp-analysis.lock.yml @@ -177,7 +177,7 @@ jobs: run: "pip install --user --quiet numpy pandas matplotlib seaborn scipy\n\n# Verify installations\npython3 -c \"import numpy; print(f'NumPy {numpy.__version__} installed')\"\npython3 -c \"import pandas; print(f'Pandas {pandas.__version__} installed')\"\npython3 -c \"import matplotlib; print(f'Matplotlib {matplotlib.__version__} installed')\"\npython3 -c \"import seaborn; print(f'Seaborn {seaborn.__version__} installed')\"\npython3 -c \"import scipy; print(f'SciPy {scipy.__version__} installed')\"\n\necho \"All scientific libraries installed successfully\"\n" - if: always() name: Upload generated charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: data-charts @@ -185,7 +185,7 @@ jobs: retention-days: 30 - if: always() name: Upload source files and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: python-source-and-data diff --git a/.github/workflows/copilot-session-insights.lock.yml b/.github/workflows/copilot-session-insights.lock.yml index cf9cf6b332..0fe64cdb80 100644 --- a/.github/workflows/copilot-session-insights.lock.yml +++ b/.github/workflows/copilot-session-insights.lock.yml @@ -184,7 +184,7 @@ jobs: run: "pip install --user --quiet numpy pandas matplotlib seaborn scipy\n\n# Verify installations\npython3 -c \"import numpy; print(f'NumPy {numpy.__version__} installed')\"\npython3 -c \"import pandas; print(f'Pandas {pandas.__version__} installed')\"\npython3 -c \"import matplotlib; print(f'Matplotlib {matplotlib.__version__} installed')\"\npython3 -c \"import seaborn; print(f'Seaborn {seaborn.__version__} installed')\"\npython3 -c \"import scipy; print(f'SciPy {scipy.__version__} installed')\"\n\necho \"All scientific libraries installed successfully\"\n" - if: always() name: Upload generated charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: data-charts @@ -192,7 +192,7 @@ jobs: retention-days: 30 - if: always() name: Upload source files and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: python-source-and-data diff --git a/.github/workflows/daily-code-metrics.lock.yml b/.github/workflows/daily-code-metrics.lock.yml index 73df188341..29c6a2d864 100644 --- a/.github/workflows/daily-code-metrics.lock.yml +++ b/.github/workflows/daily-code-metrics.lock.yml @@ -170,7 +170,7 @@ jobs: pip install --user --quiet numpy pandas matplotlib seaborn scipy - if: always() name: Upload charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: trending-charts @@ -178,7 +178,7 @@ jobs: retention-days: 30 - if: always() name: Upload source and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: trending-source-and-data diff --git a/.github/workflows/daily-copilot-token-report.lock.yml b/.github/workflows/daily-copilot-token-report.lock.yml index 3cf3f0e433..326ab27b67 100644 --- a/.github/workflows/daily-copilot-token-report.lock.yml +++ b/.github/workflows/daily-copilot-token-report.lock.yml @@ -173,7 +173,7 @@ jobs: run: "pip install --user --quiet numpy pandas matplotlib seaborn scipy\n\n# Verify installations\npython3 -c \"import numpy; print(f'NumPy {numpy.__version__} installed')\"\npython3 -c \"import pandas; print(f'Pandas {pandas.__version__} installed')\"\npython3 -c \"import matplotlib; print(f'Matplotlib {matplotlib.__version__} installed')\"\npython3 -c \"import seaborn; print(f'Seaborn {seaborn.__version__} installed')\"\npython3 -c \"import scipy; print(f'SciPy {scipy.__version__} installed')\"\n\necho \"All scientific libraries installed successfully\"\n" - if: always() name: Upload generated charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: data-charts @@ -181,7 +181,7 @@ jobs: retention-days: 30 - if: always() name: Upload source files and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: python-source-and-data diff --git a/.github/workflows/daily-file-diet.lock.yml b/.github/workflows/daily-file-diet.lock.yml index dabb92eec0..f17db90dd3 100644 --- a/.github/workflows/daily-file-diet.lock.yml +++ b/.github/workflows/daily-file-diet.lock.yml @@ -189,7 +189,7 @@ jobs: run: "pip install --user --quiet numpy pandas matplotlib seaborn scipy\n\n# Verify installations\npython3 -c \"import numpy; print(f'NumPy {numpy.__version__} installed')\"\npython3 -c \"import pandas; print(f'Pandas {pandas.__version__} installed')\"\npython3 -c \"import matplotlib; print(f'Matplotlib {matplotlib.__version__} installed')\"\npython3 -c \"import seaborn; print(f'Seaborn {seaborn.__version__} installed')\"\npython3 -c \"import scipy; print(f'SciPy {scipy.__version__} installed')\"\n\necho \"All scientific libraries installed successfully\"\n" - if: always() name: Upload generated charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: data-charts @@ -197,7 +197,7 @@ jobs: retention-days: 30 - if: always() name: Upload source files and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: python-source-and-data diff --git a/.github/workflows/daily-firewall-report.lock.yml b/.github/workflows/daily-firewall-report.lock.yml index 1ac07ac84b..83c3a510c4 100644 --- a/.github/workflows/daily-firewall-report.lock.yml +++ b/.github/workflows/daily-firewall-report.lock.yml @@ -170,7 +170,7 @@ jobs: mkdir -p /tmp/gh-aw/sandbox/agent/logs echo "Created /tmp/gh-aw/agent directory for agentic workflow temporary files" - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: cache: true go-version-file: go.mod @@ -190,7 +190,7 @@ jobs: pip install --user --quiet numpy pandas matplotlib seaborn scipy - if: always() name: Upload charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: trending-charts @@ -198,7 +198,7 @@ jobs: retention-days: 30 - if: always() name: Upload source and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: trending-source-and-data diff --git a/.github/workflows/daily-issues-report.lock.yml b/.github/workflows/daily-issues-report.lock.yml index c9bd314b75..a26cdbb13a 100644 --- a/.github/workflows/daily-issues-report.lock.yml +++ b/.github/workflows/daily-issues-report.lock.yml @@ -187,7 +187,7 @@ jobs: run: "pip install --user --quiet numpy pandas matplotlib seaborn scipy\n\n# Verify installations\npython3 -c \"import numpy; print(f'NumPy {numpy.__version__} installed')\"\npython3 -c \"import pandas; print(f'Pandas {pandas.__version__} installed')\"\npython3 -c \"import matplotlib; print(f'Matplotlib {matplotlib.__version__} installed')\"\npython3 -c \"import seaborn; print(f'Seaborn {seaborn.__version__} installed')\"\npython3 -c \"import scipy; print(f'SciPy {scipy.__version__} installed')\"\n\necho \"All scientific libraries installed successfully\"\n" - if: always() name: Upload generated charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: data-charts @@ -195,7 +195,7 @@ jobs: retention-days: 30 - if: always() name: Upload source files and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: python-source-and-data diff --git a/.github/workflows/daily-news.lock.yml b/.github/workflows/daily-news.lock.yml index 4160cddd9e..8eac6cb34e 100644 --- a/.github/workflows/daily-news.lock.yml +++ b/.github/workflows/daily-news.lock.yml @@ -179,7 +179,7 @@ jobs: run: "pip install --user --quiet numpy pandas matplotlib seaborn scipy\n\n# Verify installations\npython3 -c \"import numpy; print(f'NumPy {numpy.__version__} installed')\"\npython3 -c \"import pandas; print(f'Pandas {pandas.__version__} installed')\"\npython3 -c \"import matplotlib; print(f'Matplotlib {matplotlib.__version__} installed')\"\npython3 -c \"import seaborn; print(f'Seaborn {seaborn.__version__} installed')\"\npython3 -c \"import scipy; print(f'SciPy {scipy.__version__} installed')\"\n\necho \"All scientific libraries installed successfully\"\n" - if: always() name: Upload generated charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: data-charts @@ -187,7 +187,7 @@ jobs: retention-days: 30 - if: always() name: Upload source files and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: python-source-and-data diff --git a/.github/workflows/daily-performance-summary.lock.yml b/.github/workflows/daily-performance-summary.lock.yml index beded83902..1241567c76 100644 --- a/.github/workflows/daily-performance-summary.lock.yml +++ b/.github/workflows/daily-performance-summary.lock.yml @@ -176,7 +176,7 @@ jobs: pip install --user --quiet numpy pandas matplotlib seaborn scipy - if: always() name: Upload charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: trending-charts @@ -184,7 +184,7 @@ jobs: retention-days: 30 - if: always() name: Upload source and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: trending-source-and-data diff --git a/.github/workflows/daily-repo-chronicle.lock.yml b/.github/workflows/daily-repo-chronicle.lock.yml index eb8b4f79f8..290216ebbd 100644 --- a/.github/workflows/daily-repo-chronicle.lock.yml +++ b/.github/workflows/daily-repo-chronicle.lock.yml @@ -174,7 +174,7 @@ jobs: run: "pip install --user --quiet numpy pandas matplotlib seaborn scipy\n\n# Verify installations\npython3 -c \"import numpy; print(f'NumPy {numpy.__version__} installed')\"\npython3 -c \"import pandas; print(f'Pandas {pandas.__version__} installed')\"\npython3 -c \"import matplotlib; print(f'Matplotlib {matplotlib.__version__} installed')\"\npython3 -c \"import seaborn; print(f'Seaborn {seaborn.__version__} installed')\"\npython3 -c \"import scipy; print(f'SciPy {scipy.__version__} installed')\"\n\necho \"All scientific libraries installed successfully\"\n" - if: always() name: Upload generated charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: data-charts @@ -182,7 +182,7 @@ jobs: retention-days: 30 - if: always() name: Upload source files and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: python-source-and-data diff --git a/.github/workflows/deep-report.lock.yml b/.github/workflows/deep-report.lock.yml index eb76d0349a..d50c9b7f2e 100644 --- a/.github/workflows/deep-report.lock.yml +++ b/.github/workflows/deep-report.lock.yml @@ -179,7 +179,7 @@ jobs: name: Fetch weekly issues data run: "# Create output directories\nmkdir -p /tmp/gh-aw/weekly-issues-data\nmkdir -p /tmp/gh-aw/cache-memory\n\n# Get today's date for cache identification\nTODAY=$(date '+%Y-%m-%d')\nCACHE_DIR=\"/tmp/gh-aw/cache-memory\"\n\n# Check if cached data exists from today\nif [ -f \"$CACHE_DIR/weekly-issues-${TODAY}.json\" ] && [ -s \"$CACHE_DIR/weekly-issues-${TODAY}.json\" ]; then\n echo \"✓ Found cached weekly issues data from ${TODAY}\"\n cp \"$CACHE_DIR/weekly-issues-${TODAY}.json\" /tmp/gh-aw/weekly-issues-data/issues.json\n \n # Regenerate schema if missing\n if [ ! -f \"$CACHE_DIR/weekly-issues-${TODAY}-schema.json\" ]; then\n /tmp/gh-aw/jqschema.sh < /tmp/gh-aw/weekly-issues-data/issues.json > \"$CACHE_DIR/weekly-issues-${TODAY}-schema.json\"\n fi\n cp \"$CACHE_DIR/weekly-issues-${TODAY}-schema.json\" /tmp/gh-aw/weekly-issues-data/issues-schema.json\n \n echo \"Using cached data from ${TODAY}\"\n echo \"Total issues in cache: $(jq 'length' /tmp/gh-aw/weekly-issues-data/issues.json)\"\nelse\n echo \"⬇ Downloading fresh weekly issues data...\"\n \n # Calculate date 7 days ago (cross-platform: GNU date first, BSD fallback)\n DATE_7_DAYS_AGO=$(date -d '7 days ago' '+%Y-%m-%d' 2>/dev/null || date -v-7d '+%Y-%m-%d')\n \n echo \"Fetching issues created or updated since ${DATE_7_DAYS_AGO}...\"\n \n # Fetch issues from the last 7 days using gh CLI\n # Using --search with updated filter to get recent activity\n gh issue list --repo ${{ github.repository }} \\\n --search \"updated:>=${DATE_7_DAYS_AGO}\" \\\n --state all \\\n --json number,title,author,createdAt,state,url,body,labels,updatedAt,closedAt,milestone,assignees,comments \\\n --limit 500 \\\n > /tmp/gh-aw/weekly-issues-data/issues.json\n\n # Generate schema for reference\n /tmp/gh-aw/jqschema.sh < /tmp/gh-aw/weekly-issues-data/issues.json > /tmp/gh-aw/weekly-issues-data/issues-schema.json\n\n # Store in cache with today's date\n cp /tmp/gh-aw/weekly-issues-data/issues.json \"$CACHE_DIR/weekly-issues-${TODAY}.json\"\n cp /tmp/gh-aw/weekly-issues-data/issues-schema.json \"$CACHE_DIR/weekly-issues-${TODAY}-schema.json\"\n\n echo \"✓ Weekly issues data saved to cache: weekly-issues-${TODAY}.json\"\n echo \"Total issues found: $(jq 'length' /tmp/gh-aw/weekly-issues-data/issues.json)\"\nfi\n\n# Always ensure data is available at expected locations for backward compatibility\necho \"Weekly issues data available at: /tmp/gh-aw/weekly-issues-data/issues.json\"\necho \"Schema available at: /tmp/gh-aw/weekly-issues-data/issues-schema.json\"" - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/dev-hawk.lock.yml b/.github/workflows/dev-hawk.lock.yml index 42c2142c3a..d2614f3480 100644 --- a/.github/workflows/dev-hawk.lock.yml +++ b/.github/workflows/dev-hawk.lock.yml @@ -174,7 +174,7 @@ jobs: mkdir -p /tmp/gh-aw/sandbox/agent/logs echo "Created /tmp/gh-aw/agent directory for agentic workflow temporary files" - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/github-mcp-structural-analysis.lock.yml b/.github/workflows/github-mcp-structural-analysis.lock.yml index ac9f9f6943..0bc8dc83de 100644 --- a/.github/workflows/github-mcp-structural-analysis.lock.yml +++ b/.github/workflows/github-mcp-structural-analysis.lock.yml @@ -175,7 +175,7 @@ jobs: run: "pip install --user --quiet numpy pandas matplotlib seaborn scipy\n\n# Verify installations\npython3 -c \"import numpy; print(f'NumPy {numpy.__version__} installed')\"\npython3 -c \"import pandas; print(f'Pandas {pandas.__version__} installed')\"\npython3 -c \"import matplotlib; print(f'Matplotlib {matplotlib.__version__} installed')\"\npython3 -c \"import seaborn; print(f'Seaborn {seaborn.__version__} installed')\"\npython3 -c \"import scipy; print(f'SciPy {scipy.__version__} installed')\"\n\necho \"All scientific libraries installed successfully\"\n" - if: always() name: Upload generated charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: data-charts @@ -183,7 +183,7 @@ jobs: retention-days: 30 - if: always() name: Upload source files and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: python-source-and-data diff --git a/.github/workflows/go-pattern-detector.lock.yml b/.github/workflows/go-pattern-detector.lock.yml index 5444f90f6a..cc741976f9 100644 --- a/.github/workflows/go-pattern-detector.lock.yml +++ b/.github/workflows/go-pattern-detector.lock.yml @@ -5391,7 +5391,7 @@ jobs: found_patterns: ${{ steps.detect.outputs.found_patterns }} steps: - name: Checkout repository - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false - name: Install ast-grep diff --git a/.github/workflows/intelligence.lock.yml b/.github/workflows/intelligence.lock.yml index 66ad0dc140..02813425ac 100644 --- a/.github/workflows/intelligence.lock.yml +++ b/.github/workflows/intelligence.lock.yml @@ -182,7 +182,7 @@ jobs: run: "pip install --user --quiet numpy pandas matplotlib seaborn scipy\n\n# Verify installations\npython3 -c \"import numpy; print(f'NumPy {numpy.__version__} installed')\"\npython3 -c \"import pandas; print(f'Pandas {pandas.__version__} installed')\"\npython3 -c \"import matplotlib; print(f'Matplotlib {matplotlib.__version__} installed')\"\npython3 -c \"import seaborn; print(f'Seaborn {seaborn.__version__} installed')\"\npython3 -c \"import scipy; print(f'SciPy {scipy.__version__} installed')\"\n\necho \"All scientific libraries installed successfully\"\n" - if: always() name: Upload generated charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: data-charts @@ -190,7 +190,7 @@ jobs: retention-days: 30 - if: always() name: Upload source files and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: python-source-and-data diff --git a/.github/workflows/issue-classifier.lock.yml b/.github/workflows/issue-classifier.lock.yml index b4cd8aa7b8..0a8d23036c 100644 --- a/.github/workflows/issue-classifier.lock.yml +++ b/.github/workflows/issue-classifier.lock.yml @@ -3006,7 +3006,7 @@ jobs: path: /tmp/gh-aw/aw_info.json if-no-files-found: warn - name: Run AI Inference - uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v1 + uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v2.0.4 env: GH_AW_MCP_CONFIG: /tmp/gh-aw/mcp-config/mcp-servers.json GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt diff --git a/.github/workflows/org-health-report.lock.yml b/.github/workflows/org-health-report.lock.yml index 8984388e8b..9051469030 100644 --- a/.github/workflows/org-health-report.lock.yml +++ b/.github/workflows/org-health-report.lock.yml @@ -176,7 +176,7 @@ jobs: run: "pip install --user --quiet numpy pandas matplotlib seaborn scipy\n\n# Verify installations\npython3 -c \"import numpy; print(f'NumPy {numpy.__version__} installed')\"\npython3 -c \"import pandas; print(f'Pandas {pandas.__version__} installed')\"\npython3 -c \"import matplotlib; print(f'Matplotlib {matplotlib.__version__} installed')\"\npython3 -c \"import seaborn; print(f'Seaborn {seaborn.__version__} installed')\"\npython3 -c \"import scipy; print(f'SciPy {scipy.__version__} installed')\"\n\necho \"All scientific libraries installed successfully\"\n" - if: always() name: Upload generated charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: data-charts @@ -184,7 +184,7 @@ jobs: retention-days: 30 - if: always() name: Upload source files and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: python-source-and-data diff --git a/.github/workflows/portfolio-analyst.lock.yml b/.github/workflows/portfolio-analyst.lock.yml index 3065956dc8..d7aa6c8aa9 100644 --- a/.github/workflows/portfolio-analyst.lock.yml +++ b/.github/workflows/portfolio-analyst.lock.yml @@ -171,7 +171,7 @@ jobs: mkdir -p /tmp/gh-aw/sandbox/agent/logs echo "Created /tmp/gh-aw/agent directory for agentic workflow temporary files" - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: cache: true go-version-file: go.mod @@ -193,7 +193,7 @@ jobs: pip install --user --quiet numpy pandas matplotlib seaborn scipy - if: always() name: Upload charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: trending-charts @@ -201,7 +201,7 @@ jobs: retention-days: 30 - if: always() name: Upload source and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: trending-source-and-data diff --git a/.github/workflows/prompt-clustering-analysis.lock.yml b/.github/workflows/prompt-clustering-analysis.lock.yml index 7b01986091..f0a07ad2d6 100644 --- a/.github/workflows/prompt-clustering-analysis.lock.yml +++ b/.github/workflows/prompt-clustering-analysis.lock.yml @@ -173,7 +173,7 @@ jobs: - name: Set up jq utilities directory run: "mkdir -p /tmp/gh-aw\ncat > /tmp/gh-aw/jqschema.sh << 'EOF'\n#!/usr/bin/env bash\n# jqschema.sh\njq -c '\ndef walk(f):\n . as $in |\n if type == \"object\" then\n reduce keys[] as $k ({}; . + {($k): ($in[$k] | walk(f))})\n elif type == \"array\" then\n if length == 0 then [] else [.[0] | walk(f)] end\n else\n type\n end;\nwalk(.)\n'\nEOF\nchmod +x /tmp/gh-aw/jqschema.sh" - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: cache: true go-version-file: go.mod @@ -198,7 +198,7 @@ jobs: pip install --user --quiet numpy pandas matplotlib seaborn scipy - if: always() name: Upload charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: trending-charts @@ -206,7 +206,7 @@ jobs: retention-days: 30 - if: always() name: Upload source and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: trending-source-and-data diff --git a/.github/workflows/python-data-charts.lock.yml b/.github/workflows/python-data-charts.lock.yml index 9016dda29d..4e2d4ea778 100644 --- a/.github/workflows/python-data-charts.lock.yml +++ b/.github/workflows/python-data-charts.lock.yml @@ -172,7 +172,7 @@ jobs: run: "pip install --user --quiet numpy pandas matplotlib seaborn scipy\n\n# Verify installations\npython3 -c \"import numpy; print(f'NumPy {numpy.__version__} installed')\"\npython3 -c \"import pandas; print(f'Pandas {pandas.__version__} installed')\"\npython3 -c \"import matplotlib; print(f'Matplotlib {matplotlib.__version__} installed')\"\npython3 -c \"import seaborn; print(f'Seaborn {seaborn.__version__} installed')\"\npython3 -c \"import scipy; print(f'SciPy {scipy.__version__} installed')\"\n\necho \"All scientific libraries installed successfully\"\n" - if: always() name: Upload generated charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: data-charts @@ -180,7 +180,7 @@ jobs: retention-days: 30 - if: always() name: Upload source files and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: python-source-and-data diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index 4fcd2b0742..532c8ef4e6 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -6500,28 +6500,28 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: cache: false go-version-file: go.mod - name: Download Go modules run: go mod download - name: Generate SBOM (SPDX format) - uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.10 + uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.11 with: artifact-name: sbom.spdx.json format: spdx-json output-file: sbom.spdx.json - name: Generate SBOM (CycloneDX format) - uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.10 + uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.11 with: artifact-name: sbom.cdx.json format: cyclonedx-json output-file: sbom.cdx.json - name: Upload SBOM artifacts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: name: sbom-artifacts path: | @@ -6700,12 +6700,12 @@ jobs: release_tag: ${{ steps.get_release.outputs.release_tag }} steps: - name: Checkout - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: fetch-depth: 0 persist-credentials: false - name: Release with gh-extension-precompile - uses: cli/gh-extension-precompile@9e2237c30f869ad3bcaed6a4be2cd43564dd421b # v2 + uses: cli/gh-extension-precompile@9e2237c30f869ad3bcaed6a4be2cd43564dd421b # v2.1.0 with: build_script_override: scripts/build-release.sh go_version_file: go.mod diff --git a/.github/workflows/safe-output-health.lock.yml b/.github/workflows/safe-output-health.lock.yml index 5b82eb490c..83b39a201c 100644 --- a/.github/workflows/safe-output-health.lock.yml +++ b/.github/workflows/safe-output-health.lock.yml @@ -167,7 +167,7 @@ jobs: mkdir -p /tmp/gh-aw/sandbox/agent/logs echo "Created /tmp/gh-aw/agent directory for agentic workflow temporary files" - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/slide-deck-maintainer.lock.yml b/.github/workflows/slide-deck-maintainer.lock.yml index 16a1bceb66..c0b7d7d7ed 100644 --- a/.github/workflows/slide-deck-maintainer.lock.yml +++ b/.github/workflows/slide-deck-maintainer.lock.yml @@ -167,7 +167,7 @@ jobs: mkdir -p /tmp/gh-aw/sandbox/agent/logs echo "Created /tmp/gh-aw/agent directory for agentic workflow temporary files" - name: Set up Node.js - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6 + uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 with: cache: npm cache-dependency-path: docs/package-lock.json diff --git a/.github/workflows/smoke-copilot-playwright.lock.yml b/.github/workflows/smoke-copilot-playwright.lock.yml index 71c6933c71..9e4948c85a 100644 --- a/.github/workflows/smoke-copilot-playwright.lock.yml +++ b/.github/workflows/smoke-copilot-playwright.lock.yml @@ -7635,7 +7635,7 @@ jobs: run: "echo \"📋 Collecting Playwright MCP logs...\"\n\n# Create logs directory\nmkdir -p /tmp/gh-aw/playwright-debug-logs\n\n# Copy any playwright logs from the MCP logs directory\nif [ -d \"/tmp/gh-aw/mcp-logs/playwright\" ]; then\n echo \"Found Playwright MCP logs directory\"\n cp -r /tmp/gh-aw/mcp-logs/playwright/* /tmp/gh-aw/playwright-debug-logs/ 2>/dev/null || true\n ls -la /tmp/gh-aw/playwright-debug-logs/\nelse\n echo \"No Playwright MCP logs directory found at /tmp/gh-aw/mcp-logs/playwright\"\nfi\n\n# List all trace files if any\necho \"Looking for trace files...\"\nfind /tmp -name \"*.zip\" -o -name \"trace*\" 2>/dev/null | head -20 || true\n\n# Show docker container logs if any containers are still running\necho \"Checking for running Docker containers...\"\ndocker ps -a --format \"table {{.Names}}\\t{{.Status}}\\t{{.Image}}\" 2>/dev/null || true\n" - if: always() name: Upload Playwright Debug Logs - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: ignore name: playwright-debug-logs-${{ github.run_id }} diff --git a/.github/workflows/smoke-detector.lock.yml b/.github/workflows/smoke-detector.lock.yml index da99b69e2a..599b02c984 100644 --- a/.github/workflows/smoke-detector.lock.yml +++ b/.github/workflows/smoke-detector.lock.yml @@ -595,7 +595,7 @@ jobs: mkdir -p /tmp/gh-aw/sandbox/agent/logs echo "Created /tmp/gh-aw/agent directory for agentic workflow temporary files" - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/stale-repo-identifier.lock.yml b/.github/workflows/stale-repo-identifier.lock.yml index cafa2d4a1c..9826f0b420 100644 --- a/.github/workflows/stale-repo-identifier.lock.yml +++ b/.github/workflows/stale-repo-identifier.lock.yml @@ -184,7 +184,7 @@ jobs: run: "pip install --user --quiet numpy pandas matplotlib seaborn scipy\n\n# Verify installations\npython3 -c \"import numpy; print(f'NumPy {numpy.__version__} installed')\"\npython3 -c \"import pandas; print(f'Pandas {pandas.__version__} installed')\"\npython3 -c \"import matplotlib; print(f'Matplotlib {matplotlib.__version__} installed')\"\npython3 -c \"import seaborn; print(f'Seaborn {seaborn.__version__} installed')\"\npython3 -c \"import scipy; print(f'SciPy {scipy.__version__} installed')\"\n\necho \"All scientific libraries installed successfully\"\n" - if: always() name: Upload generated charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: data-charts @@ -192,7 +192,7 @@ jobs: retention-days: 30 - if: always() name: Upload source files and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: python-source-and-data @@ -208,7 +208,7 @@ jobs: pip install --user --quiet numpy pandas matplotlib seaborn scipy - if: always() name: Upload charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: trending-charts @@ -216,7 +216,7 @@ jobs: retention-days: 30 - if: always() name: Upload source and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: trending-source-and-data diff --git a/.github/workflows/static-analysis-report.lock.yml b/.github/workflows/static-analysis-report.lock.yml index 01e0ea8511..bc200661d9 100644 --- a/.github/workflows/static-analysis-report.lock.yml +++ b/.github/workflows/static-analysis-report.lock.yml @@ -166,7 +166,7 @@ jobs: mkdir -p /tmp/gh-aw/sandbox/agent/logs echo "Created /tmp/gh-aw/agent directory for agentic workflow temporary files" - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/super-linter.lock.yml b/.github/workflows/super-linter.lock.yml index d5a2f30d5c..0dd7aa278a 100644 --- a/.github/workflows/super-linter.lock.yml +++ b/.github/workflows/super-linter.lock.yml @@ -166,7 +166,7 @@ jobs: mkdir -p /tmp/gh-aw/sandbox/agent/logs echo "Created /tmp/gh-aw/agent directory for agentic workflow temporary files" - name: Download super-linter log - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6 + uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 with: name: super-linter-log path: /tmp/gh-aw/ @@ -7547,13 +7547,13 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: fetch-depth: 0 persist-credentials: false - name: Super-linter id: super-linter - uses: super-linter/super-linter@47984f49b4e87383eed97890fe2dca6063bbd9c3 # v8.2.1 + uses: super-linter/super-linter@47984f49b4e87383eed97890fe2dca6063bbd9c3 # v8.3.1 env: CREATE_LOG_FILE: "true" DEFAULT_BRANCH: main @@ -7575,7 +7575,7 @@ jobs: fi - name: Upload super-linter log if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: name: super-linter-log path: super-linter.log diff --git a/.github/workflows/tidy.lock.yml b/.github/workflows/tidy.lock.yml index f3dcc5ef32..840170e2de 100644 --- a/.github/workflows/tidy.lock.yml +++ b/.github/workflows/tidy.lock.yml @@ -577,13 +577,13 @@ jobs: mkdir -p /tmp/gh-aw/sandbox/agent/logs echo "Created /tmp/gh-aw/agent directory for agentic workflow temporary files" - name: Set up Node.js - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6 + uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 with: cache: npm cache-dependency-path: pkg/workflow/js/package-lock.json node-version: "24" - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6 + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/weekly-issue-summary.lock.yml b/.github/workflows/weekly-issue-summary.lock.yml index 17588260c5..0551f3ad7c 100644 --- a/.github/workflows/weekly-issue-summary.lock.yml +++ b/.github/workflows/weekly-issue-summary.lock.yml @@ -167,7 +167,7 @@ jobs: run: "pip install --user --quiet numpy pandas matplotlib seaborn scipy\n\n# Verify installations\npython3 -c \"import numpy; print(f'NumPy {numpy.__version__} installed')\"\npython3 -c \"import pandas; print(f'Pandas {pandas.__version__} installed')\"\npython3 -c \"import matplotlib; print(f'Matplotlib {matplotlib.__version__} installed')\"\npython3 -c \"import seaborn; print(f'Seaborn {seaborn.__version__} installed')\"\npython3 -c \"import scipy; print(f'SciPy {scipy.__version__} installed')\"\n\necho \"All scientific libraries installed successfully\"\n" - if: always() name: Upload generated charts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: data-charts @@ -175,7 +175,7 @@ jobs: retention-days: 30 - if: always() name: Upload source files and data - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 with: if-no-files-found: warn name: python-source-and-data diff --git a/pkg/workflow/compiler_safe_outputs_consolidated.go b/pkg/workflow/compiler_safe_outputs_core.go similarity index 50% rename from pkg/workflow/compiler_safe_outputs_consolidated.go rename to pkg/workflow/compiler_safe_outputs_core.go index 3cbbabe23e..c351100952 100644 --- a/pkg/workflow/compiler_safe_outputs_consolidated.go +++ b/pkg/workflow/compiler_safe_outputs_core.go @@ -672,697 +672,3 @@ func buildDetectionSuccessCondition() ConditionNode { BuildStringLiteral("true"), ) } - -// === Step Config Builders === -// These functions build the SafeOutputStepConfig for each safe output type - -func (c *Compiler) buildCreateIssueStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.CreateIssues - - var customEnvVars []string - customEnvVars = append(customEnvVars, buildTitlePrefixEnvVar("GH_AW_ISSUE_TITLE_PREFIX", cfg.TitlePrefix)...) - customEnvVars = append(customEnvVars, buildLabelsEnvVar("GH_AW_ISSUE_LABELS", cfg.Labels)...) - customEnvVars = append(customEnvVars, buildLabelsEnvVar("GH_AW_ISSUE_ALLOWED_LABELS", cfg.AllowedLabels)...) - customEnvVars = append(customEnvVars, buildAllowedReposEnvVar("GH_AW_ALLOWED_REPOS", cfg.AllowedRepos)...) - if cfg.Expires > 0 { - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_ISSUE_EXPIRES: \"%d\"\n", cfg.Expires)) - } - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, cfg.TargetRepoSlug)...) - - condition := BuildSafeOutputType("create_issue") - - return SafeOutputStepConfig{ - StepName: "Create Issue", - StepID: "create_issue", - ScriptName: "create_issue", - Script: getCreateIssueScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildCreateDiscussionStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.CreateDiscussions - - var customEnvVars []string - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("create_discussion") - - return SafeOutputStepConfig{ - StepName: "Create Discussion", - StepID: "create_discussion", - ScriptName: "create_discussion", - Script: getCreateDiscussionScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildCreatePullRequestStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.CreatePullRequests - - var customEnvVars []string - // Pass the base branch from GitHub context (required by create_pull_request.cjs) - // Note: GH_AW_WORKFLOW_ID is now set at the job level and inherited by all steps - customEnvVars = append(customEnvVars, " GH_AW_BASE_BRANCH: ${{ github.ref_name }}\n") - customEnvVars = append(customEnvVars, buildTitlePrefixEnvVar("GH_AW_PR_TITLE_PREFIX", cfg.TitlePrefix)...) - customEnvVars = append(customEnvVars, buildLabelsEnvVar("GH_AW_PR_LABELS", cfg.Labels)...) - customEnvVars = append(customEnvVars, buildLabelsEnvVar("GH_AW_PR_ALLOWED_LABELS", cfg.AllowedLabels)...) - // Add draft setting - always set with default to true for backwards compatibility - draftValue := true // Default value - if cfg.Draft != nil { - draftValue = *cfg.Draft - } - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_PR_DRAFT: %q\n", fmt.Sprintf("%t", draftValue))) - // Add if-no-changes setting - always set with default to "warn" - ifNoChanges := cfg.IfNoChanges - if ifNoChanges == "" { - ifNoChanges = "warn" // Default value - } - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_PR_IF_NO_CHANGES: %q\n", ifNoChanges)) - // Add allow-empty setting - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_PR_ALLOW_EMPTY: %q\n", fmt.Sprintf("%t", cfg.AllowEmpty))) - // Add max patch size setting - maxPatchSize := 1024 // default 1024 KB - if data.SafeOutputs.MaximumPatchSize > 0 { - maxPatchSize = data.SafeOutputs.MaximumPatchSize - } - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_MAX_PATCH_SIZE: %d\n", maxPatchSize)) - // Add activation comment information if available (for updating the comment with PR link) - if data.AIReaction != "" && data.AIReaction != "none" { - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_COMMENT_ID: ${{ needs.%s.outputs.comment_id }}\n", constants.ActivationJobName)) - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_COMMENT_REPO: ${{ needs.%s.outputs.comment_repo }}\n", constants.ActivationJobName)) - } - // Add expires value if set (only for same-repo PRs - when target-repo is not set) - if cfg.Expires > 0 && cfg.TargetRepoSlug == "" { - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_PR_EXPIRES: \"%d\"\n", cfg.Expires)) - } - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, cfg.TargetRepoSlug)...) - - condition := BuildSafeOutputType("create_pull_request") - - // Build pre-steps for checkout and git config - preSteps := c.buildCreatePullRequestPreStepsConsolidated(data, cfg, condition) - - return SafeOutputStepConfig{ - StepName: "Create Pull Request", - StepID: "create_pull_request", - ScriptName: "create_pull_request", - Script: getCreatePullRequestScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - PreSteps: preSteps, - } -} - -func (c *Compiler) buildAddCommentStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool, createIssueEnabled, createDiscussionEnabled, createPullRequestEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.AddComments - - var customEnvVars []string - if cfg.Target != "" { - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_COMMENT_TARGET: %q\n", cfg.Target)) - } - if cfg.Discussion != nil && *cfg.Discussion { - customEnvVars = append(customEnvVars, " GITHUB_AW_COMMENT_DISCUSSION: \"true\"\n") - } - if cfg.HideOlderComments { - customEnvVars = append(customEnvVars, " GH_AW_HIDE_OLDER_COMMENTS: \"true\"\n") - } - - // Reference outputs from earlier steps in the same job - if createIssueEnabled { - customEnvVars = append(customEnvVars, " GH_AW_CREATED_ISSUE_URL: ${{ steps.create_issue.outputs.issue_url }}\n") - customEnvVars = append(customEnvVars, " GH_AW_CREATED_ISSUE_NUMBER: ${{ steps.create_issue.outputs.issue_number }}\n") - customEnvVars = append(customEnvVars, " GH_AW_TEMPORARY_ID_MAP: ${{ steps.create_issue.outputs.temporary_id_map }}\n") - } - if createDiscussionEnabled { - customEnvVars = append(customEnvVars, " GH_AW_CREATED_DISCUSSION_URL: ${{ steps.create_discussion.outputs.discussion_url }}\n") - customEnvVars = append(customEnvVars, " GH_AW_CREATED_DISCUSSION_NUMBER: ${{ steps.create_discussion.outputs.discussion_number }}\n") - } - if createPullRequestEnabled { - customEnvVars = append(customEnvVars, " GH_AW_CREATED_PULL_REQUEST_URL: ${{ steps.create_pull_request.outputs.pull_request_url }}\n") - customEnvVars = append(customEnvVars, " GH_AW_CREATED_PULL_REQUEST_NUMBER: ${{ steps.create_pull_request.outputs.pull_request_number }}\n") - } - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, cfg.TargetRepoSlug)...) - - condition := BuildSafeOutputType("add_comment") - - return SafeOutputStepConfig{ - StepName: "Add Comment", - StepID: "add_comment", - ScriptName: "add_comment", - Script: getAddCommentScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildCloseDiscussionStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.CloseDiscussions - - var customEnvVars []string - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("close_discussion") - - return SafeOutputStepConfig{ - StepName: "Close Discussion", - StepID: "close_discussion", - ScriptName: "close_discussion", - Script: getCloseDiscussionScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildCloseIssueStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.CloseIssues - - var customEnvVars []string - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("close_issue") - - return SafeOutputStepConfig{ - StepName: "Close Issue", - StepID: "close_issue", - ScriptName: "close_issue", - Script: getCloseIssueScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildClosePullRequestStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.ClosePullRequests - - var customEnvVars []string - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("close_pull_request") - - return SafeOutputStepConfig{ - StepName: "Close Pull Request", - StepID: "close_pull_request", - ScriptName: "close_pull_request", - Script: getClosePullRequestScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildCreatePRReviewCommentStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.CreatePullRequestReviewComments - - var customEnvVars []string - // Add side configuration - if cfg.Side != "" { - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_PR_REVIEW_COMMENT_SIDE: %q\n", cfg.Side)) - } - // Add target configuration - if cfg.Target != "" { - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_PR_REVIEW_COMMENT_TARGET: %q\n", cfg.Target)) - } - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("create_pull_request_review_comment") - - return SafeOutputStepConfig{ - StepName: "Create PR Review Comment", - StepID: "create_pr_review_comment", - ScriptName: "create_pr_review_comment", - Script: getCreatePRReviewCommentScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildCreateCodeScanningAlertStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool, workflowFilename string) SafeOutputStepConfig { - cfg := data.SafeOutputs.CreateCodeScanningAlerts - - var customEnvVars []string - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_WORKFLOW_FILENAME: %q\n", workflowFilename)) - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("create_code_scanning_alert") - - return SafeOutputStepConfig{ - StepName: "Create Code Scanning Alert", - StepID: "create_code_scanning_alert", - ScriptName: "create_code_scanning_alert", - Script: getCreateCodeScanningAlertScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildAddLabelsStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.AddLabels - - var customEnvVars []string - customEnvVars = append(customEnvVars, buildLabelsEnvVar("GH_AW_LABELS_ALLOWED", cfg.Allowed)...) - if cfg.Max > 0 { - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_LABELS_MAX_COUNT: %d\n", cfg.Max)) - } - if cfg.Target != "" { - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_LABELS_TARGET: %q\n", cfg.Target)) - } - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, cfg.TargetRepoSlug)...) - - condition := BuildSafeOutputType("add_labels") - - return SafeOutputStepConfig{ - StepName: "Add Labels", - StepID: "add_labels", - ScriptName: "add_labels", - Script: getAddLabelsScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildAddReviewerStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.AddReviewer - - var customEnvVars []string - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("add_reviewer") - - return SafeOutputStepConfig{ - StepName: "Add Reviewer", - StepID: "add_reviewer", - ScriptName: "add_reviewer", - Script: getAddReviewerScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildAssignMilestoneStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.AssignMilestone - - var customEnvVars []string - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("assign_milestone") - - return SafeOutputStepConfig{ - StepName: "Assign Milestone", - StepID: "assign_milestone", - ScriptName: "assign_milestone", - Script: getAssignMilestoneScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildAssignToAgentStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.AssignToAgent - - var customEnvVars []string - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("assign_to_agent") - - return SafeOutputStepConfig{ - StepName: "Assign To Agent", - StepID: "assign_to_agent", - ScriptName: "assign_to_agent", - Script: getAssignToAgentScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - UseAgentToken: true, - } -} - -func (c *Compiler) buildAssignToUserStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.AssignToUser - - var customEnvVars []string - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("assign_to_user") - - return SafeOutputStepConfig{ - StepName: "Assign To User", - StepID: "assign_to_user", - ScriptName: "assign_to_user", - Script: getAssignToUserScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildUpdateIssueStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.UpdateIssues - - var customEnvVars []string - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, cfg.TargetRepoSlug)...) - - condition := BuildSafeOutputType("update_issue") - - return SafeOutputStepConfig{ - StepName: "Update Issue", - StepID: "update_issue", - ScriptName: "update_issue", - Script: getUpdateIssueScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildUpdatePullRequestStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.UpdatePullRequests - - var customEnvVars []string - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, cfg.TargetRepoSlug)...) - - condition := BuildSafeOutputType("update_pull_request") - - return SafeOutputStepConfig{ - StepName: "Update Pull Request", - StepID: "update_pull_request", - ScriptName: "update_pull_request", - Script: getUpdatePullRequestScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildUpdateDiscussionStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.UpdateDiscussions - - var customEnvVars []string - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, cfg.TargetRepoSlug)...) - - // Add target environment variable if set - if cfg.Target != "" { - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_UPDATE_TARGET: %q\n", cfg.Target)) - } - - // Add field update flags - presence of pointer indicates field can be updated - if cfg.Title != nil { - customEnvVars = append(customEnvVars, " GH_AW_UPDATE_TITLE: \"true\"\n") - } - if cfg.Body != nil { - customEnvVars = append(customEnvVars, " GH_AW_UPDATE_BODY: \"true\"\n") - } - if cfg.Labels != nil { - customEnvVars = append(customEnvVars, " GH_AW_UPDATE_LABELS: \"true\"\n") - } - - condition := BuildSafeOutputType("update_discussion") - - return SafeOutputStepConfig{ - StepName: "Update Discussion", - StepID: "update_discussion", - ScriptName: "update_discussion", - Script: getUpdateDiscussionScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildPushToPullRequestBranchStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.PushToPullRequestBranch - - var customEnvVars []string - // Add target config if set - if cfg.Target != "" { - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_PUSH_TARGET: %q\n", cfg.Target)) - } - // Add if-no-changes config if set - if cfg.IfNoChanges != "" { - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_PUSH_IF_NO_CHANGES: %q\n", cfg.IfNoChanges)) - } - // Add title prefix if set (using same env var as create-pull-request) - customEnvVars = append(customEnvVars, buildTitlePrefixEnvVar("GH_AW_PR_TITLE_PREFIX", cfg.TitlePrefix)...) - // Add labels if set - customEnvVars = append(customEnvVars, buildLabelsEnvVar("GH_AW_PR_LABELS", cfg.Labels)...) - // Add commit title suffix if set - if cfg.CommitTitleSuffix != "" { - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_COMMIT_TITLE_SUFFIX: %q\n", cfg.CommitTitleSuffix)) - } - // Add max patch size setting - maxPatchSize := 1024 // default 1024 KB - if data.SafeOutputs.MaximumPatchSize > 0 { - maxPatchSize = data.SafeOutputs.MaximumPatchSize - } - customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_MAX_PATCH_SIZE: %d\n", maxPatchSize)) - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("push_to_pull_request_branch") - - // Build pre-steps for checkout and git config - preSteps := c.buildPushToPullRequestBranchPreStepsConsolidated(data, cfg, condition) - - return SafeOutputStepConfig{ - StepName: "Push To Pull Request Branch", - StepID: "push_to_pull_request_branch", - ScriptName: "push_to_pull_request_branch", - Script: getPushToPullRequestBranchScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - PreSteps: preSteps, - } -} - -func (c *Compiler) buildUploadAssetsStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.UploadAssets - - var customEnvVars []string - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("upload_asset") - - return SafeOutputStepConfig{ - StepName: "Upload Assets", - StepID: "upload_assets", - ScriptName: "upload_assets", - Script: getUploadAssetsScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildUpdateReleaseStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.UpdateRelease - - var customEnvVars []string - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("update_release") - - return SafeOutputStepConfig{ - StepName: "Update Release", - StepID: "update_release", - ScriptName: "update_release", - Script: getUpdateReleaseScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildLinkSubIssueStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool, createIssueEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.LinkSubIssue - - var customEnvVars []string - if createIssueEnabled { - customEnvVars = append(customEnvVars, " GH_AW_CREATED_ISSUE_NUMBER: ${{ steps.create_issue.outputs.issue_number }}\n") - customEnvVars = append(customEnvVars, " GH_AW_TEMPORARY_ID_MAP: ${{ steps.create_issue.outputs.temporary_id_map }}\n") - } - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("link_sub_issue") - - return SafeOutputStepConfig{ - StepName: "Link Sub Issue", - StepID: "link_sub_issue", - ScriptName: "link_sub_issue", - Script: getLinkSubIssueScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildHideCommentStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.HideComment - - var customEnvVars []string - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("hide_comment") - - return SafeOutputStepConfig{ - StepName: "Hide Comment", - StepID: "hide_comment", - ScriptName: "hide_comment", - Script: getHideCommentScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -func (c *Compiler) buildCreateAgentTaskStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.CreateAgentTasks - - var customEnvVars []string - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("create_agent_task") - - return SafeOutputStepConfig{ - StepName: "Create Agent Task", - StepID: "create_agent_task", - Script: createAgentTaskScript, - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - UseCopilotToken: true, - } -} - -func (c *Compiler) buildUpdateProjectStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { - cfg := data.SafeOutputs.UpdateProjects - - var customEnvVars []string - customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) - - condition := BuildSafeOutputType("update_project") - - return SafeOutputStepConfig{ - StepName: "Update Project", - StepID: "update_project", - ScriptName: "update_project", - Script: getUpdateProjectScript(), - CustomEnvVars: customEnvVars, - Condition: condition, - Token: cfg.GitHubToken, - } -} - -// buildCreatePullRequestPreSteps builds the pre-steps for create-pull-request -func (c *Compiler) buildCreatePullRequestPreStepsConsolidated(data *WorkflowData, cfg *CreatePullRequestsConfig, condition ConditionNode) []string { - var preSteps []string - - // Determine which token to use for checkout - // If an app is configured, use the app token; otherwise use the default github.token - var checkoutToken string - var gitRemoteToken string - if data.SafeOutputs.App != nil { - checkoutToken = "${{ steps.app-token.outputs.token }}" - gitRemoteToken = "${{ steps.app-token.outputs.token }}" - } else { - checkoutToken = "${{ github.token }}" - gitRemoteToken = "${{ github.token }}" - } - - // Step 1: Checkout repository with conditional execution - preSteps = append(preSteps, " - name: Checkout repository\n") - // Add the condition to only checkout if create_pull_request will run - preSteps = append(preSteps, fmt.Sprintf(" if: %s\n", condition.Render())) - preSteps = append(preSteps, fmt.Sprintf(" uses: %s\n", GetActionPin("actions/checkout"))) - preSteps = append(preSteps, " with:\n") - preSteps = append(preSteps, fmt.Sprintf(" token: %s\n", checkoutToken)) - preSteps = append(preSteps, " persist-credentials: false\n") - preSteps = append(preSteps, " fetch-depth: 1\n") - if c.trialMode { - if c.trialLogicalRepoSlug != "" { - preSteps = append(preSteps, fmt.Sprintf(" repository: %s\n", c.trialLogicalRepoSlug)) - } - } - - // Step 2: Configure Git credentials with conditional execution - gitConfigSteps := []string{ - " - name: Configure Git credentials\n", - fmt.Sprintf(" if: %s\n", condition.Render()), - " env:\n", - " REPO_NAME: ${{ github.repository }}\n", - " SERVER_URL: ${{ github.server_url }}\n", - " run: |\n", - " git config --global user.email \"github-actions[bot]@users.noreply.github.com\"\n", - " git config --global user.name \"github-actions[bot]\"\n", - " # Re-authenticate git with GitHub token\n", - " SERVER_URL_STRIPPED=\"${SERVER_URL#https://}\"\n", - fmt.Sprintf(" git remote set-url origin \"https://x-access-token:%s@${SERVER_URL_STRIPPED}/${REPO_NAME}.git\"\n", gitRemoteToken), - " echo \"Git configured with standard GitHub Actions identity\"\n", - } - preSteps = append(preSteps, gitConfigSteps...) - - return preSteps -} - -// buildPushToPullRequestBranchPreSteps builds the pre-steps for push-to-pull-request-branch -func (c *Compiler) buildPushToPullRequestBranchPreStepsConsolidated(data *WorkflowData, cfg *PushToPullRequestBranchConfig, condition ConditionNode) []string { - var preSteps []string - - // Determine which token to use for checkout - // If an app is configured, use the app token; otherwise use the default github.token - var checkoutToken string - var gitRemoteToken string - if data.SafeOutputs.App != nil { - checkoutToken = "${{ steps.app-token.outputs.token }}" - gitRemoteToken = "${{ steps.app-token.outputs.token }}" - } else { - checkoutToken = "${{ github.token }}" - gitRemoteToken = "${{ github.token }}" - } - - // Step 1: Checkout repository with conditional execution - preSteps = append(preSteps, " - name: Checkout repository\n") - // Add the condition to only checkout if push_to_pull_request_branch will run - preSteps = append(preSteps, fmt.Sprintf(" if: %s\n", condition.Render())) - preSteps = append(preSteps, fmt.Sprintf(" uses: %s\n", GetActionPin("actions/checkout"))) - preSteps = append(preSteps, " with:\n") - preSteps = append(preSteps, fmt.Sprintf(" token: %s\n", checkoutToken)) - preSteps = append(preSteps, " persist-credentials: false\n") - preSteps = append(preSteps, " fetch-depth: 1\n") - if c.trialMode { - if c.trialLogicalRepoSlug != "" { - preSteps = append(preSteps, fmt.Sprintf(" repository: %s\n", c.trialLogicalRepoSlug)) - } - } - - // Step 2: Configure Git credentials with conditional execution - gitConfigSteps := []string{ - " - name: Configure Git credentials\n", - fmt.Sprintf(" if: %s\n", condition.Render()), - " env:\n", - " REPO_NAME: ${{ github.repository }}\n", - " SERVER_URL: ${{ github.server_url }}\n", - " run: |\n", - " git config --global user.email \"github-actions[bot]@users.noreply.github.com\"\n", - " git config --global user.name \"github-actions[bot]\"\n", - " # Re-authenticate git with GitHub token\n", - " SERVER_URL_STRIPPED=\"${SERVER_URL#https://}\"\n", - fmt.Sprintf(" git remote set-url origin \"https://x-access-token:%s@${SERVER_URL_STRIPPED}/${REPO_NAME}.git\"\n", gitRemoteToken), - " echo \"Git configured with standard GitHub Actions identity\"\n", - } - preSteps = append(preSteps, gitConfigSteps...) - - return preSteps -} diff --git a/pkg/workflow/compiler_safe_outputs_discussions.go b/pkg/workflow/compiler_safe_outputs_discussions.go new file mode 100644 index 0000000000..78463125f2 --- /dev/null +++ b/pkg/workflow/compiler_safe_outputs_discussions.go @@ -0,0 +1,79 @@ +package workflow + +import "fmt" + +// buildCreateDiscussionStepConfig builds the configuration for creating a discussion +func (c *Compiler) buildCreateDiscussionStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.CreateDiscussions + + var customEnvVars []string + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("create_discussion") + + return SafeOutputStepConfig{ + StepName: "Create Discussion", + StepID: "create_discussion", + ScriptName: "create_discussion", + Script: getCreateDiscussionScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} + +// buildCloseDiscussionStepConfig builds the configuration for closing a discussion +func (c *Compiler) buildCloseDiscussionStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.CloseDiscussions + + var customEnvVars []string + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("close_discussion") + + return SafeOutputStepConfig{ + StepName: "Close Discussion", + StepID: "close_discussion", + ScriptName: "close_discussion", + Script: getCloseDiscussionScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} + +// buildUpdateDiscussionStepConfig builds the configuration for updating a discussion +func (c *Compiler) buildUpdateDiscussionStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.UpdateDiscussions + + var customEnvVars []string + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, cfg.TargetRepoSlug)...) + + // Add target environment variable if set + if cfg.Target != "" { + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_UPDATE_TARGET: %q\n", cfg.Target)) + } + + // Add field update flags - presence of pointer indicates field can be updated + if cfg.Title != nil { + customEnvVars = append(customEnvVars, " GH_AW_UPDATE_TITLE: \"true\"\n") + } + if cfg.Body != nil { + customEnvVars = append(customEnvVars, " GH_AW_UPDATE_BODY: \"true\"\n") + } + if cfg.Labels != nil { + customEnvVars = append(customEnvVars, " GH_AW_UPDATE_LABELS: \"true\"\n") + } + + condition := BuildSafeOutputType("update_discussion") + + return SafeOutputStepConfig{ + StepName: "Update Discussion", + StepID: "update_discussion", + ScriptName: "update_discussion", + Script: getUpdateDiscussionScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} diff --git a/pkg/workflow/compiler_safe_outputs_issues.go b/pkg/workflow/compiler_safe_outputs_issues.go new file mode 100644 index 0000000000..ddeeaffcdd --- /dev/null +++ b/pkg/workflow/compiler_safe_outputs_issues.go @@ -0,0 +1,94 @@ +package workflow + +import "fmt" + +// buildCreateIssueStepConfig builds the configuration for creating an issue +func (c *Compiler) buildCreateIssueStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.CreateIssues + + var customEnvVars []string + customEnvVars = append(customEnvVars, buildTitlePrefixEnvVar("GH_AW_ISSUE_TITLE_PREFIX", cfg.TitlePrefix)...) + customEnvVars = append(customEnvVars, buildLabelsEnvVar("GH_AW_ISSUE_LABELS", cfg.Labels)...) + customEnvVars = append(customEnvVars, buildLabelsEnvVar("GH_AW_ISSUE_ALLOWED_LABELS", cfg.AllowedLabels)...) + customEnvVars = append(customEnvVars, buildAllowedReposEnvVar("GH_AW_ALLOWED_REPOS", cfg.AllowedRepos)...) + if cfg.Expires > 0 { + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_ISSUE_EXPIRES: \"%d\"\n", cfg.Expires)) + } + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, cfg.TargetRepoSlug)...) + + condition := BuildSafeOutputType("create_issue") + + return SafeOutputStepConfig{ + StepName: "Create Issue", + StepID: "create_issue", + ScriptName: "create_issue", + Script: getCreateIssueScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} + +// buildCloseIssueStepConfig builds the configuration for closing an issue +func (c *Compiler) buildCloseIssueStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.CloseIssues + + var customEnvVars []string + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("close_issue") + + return SafeOutputStepConfig{ + StepName: "Close Issue", + StepID: "close_issue", + ScriptName: "close_issue", + Script: getCloseIssueScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} + +// buildUpdateIssueStepConfig builds the configuration for updating an issue +func (c *Compiler) buildUpdateIssueStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.UpdateIssues + + var customEnvVars []string + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, cfg.TargetRepoSlug)...) + + condition := BuildSafeOutputType("update_issue") + + return SafeOutputStepConfig{ + StepName: "Update Issue", + StepID: "update_issue", + ScriptName: "update_issue", + Script: getUpdateIssueScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} + +// buildLinkSubIssueStepConfig builds the configuration for linking a sub-issue +func (c *Compiler) buildLinkSubIssueStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool, createIssueEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.LinkSubIssue + + var customEnvVars []string + if createIssueEnabled { + customEnvVars = append(customEnvVars, " GH_AW_CREATED_ISSUE_NUMBER: ${{ steps.create_issue.outputs.issue_number }}\n") + customEnvVars = append(customEnvVars, " GH_AW_TEMPORARY_ID_MAP: ${{ steps.create_issue.outputs.temporary_id_map }}\n") + } + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("link_sub_issue") + + return SafeOutputStepConfig{ + StepName: "Link Sub Issue", + StepID: "link_sub_issue", + ScriptName: "link_sub_issue", + Script: getLinkSubIssueScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} diff --git a/pkg/workflow/compiler_safe_outputs_prs.go b/pkg/workflow/compiler_safe_outputs_prs.go new file mode 100644 index 0000000000..a257569cbf --- /dev/null +++ b/pkg/workflow/compiler_safe_outputs_prs.go @@ -0,0 +1,304 @@ +package workflow + +import ( + "fmt" + + "github.com/githubnext/gh-aw/pkg/constants" +) + +// buildCreatePullRequestStepConfig builds the configuration for creating a pull request +func (c *Compiler) buildCreatePullRequestStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.CreatePullRequests + + var customEnvVars []string + // Pass the base branch from GitHub context (required by create_pull_request.cjs) + // Note: GH_AW_WORKFLOW_ID is now set at the job level and inherited by all steps + customEnvVars = append(customEnvVars, " GH_AW_BASE_BRANCH: ${{ github.ref_name }}\n") + customEnvVars = append(customEnvVars, buildTitlePrefixEnvVar("GH_AW_PR_TITLE_PREFIX", cfg.TitlePrefix)...) + customEnvVars = append(customEnvVars, buildLabelsEnvVar("GH_AW_PR_LABELS", cfg.Labels)...) + customEnvVars = append(customEnvVars, buildLabelsEnvVar("GH_AW_PR_ALLOWED_LABELS", cfg.AllowedLabels)...) + // Add draft setting - always set with default to true for backwards compatibility + draftValue := true // Default value + if cfg.Draft != nil { + draftValue = *cfg.Draft + } + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_PR_DRAFT: %q\n", fmt.Sprintf("%t", draftValue))) + // Add if-no-changes setting - always set with default to "warn" + ifNoChanges := cfg.IfNoChanges + if ifNoChanges == "" { + ifNoChanges = "warn" // Default value + } + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_PR_IF_NO_CHANGES: %q\n", ifNoChanges)) + // Add allow-empty setting + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_PR_ALLOW_EMPTY: %q\n", fmt.Sprintf("%t", cfg.AllowEmpty))) + // Add max patch size setting + maxPatchSize := 1024 // default 1024 KB + if data.SafeOutputs.MaximumPatchSize > 0 { + maxPatchSize = data.SafeOutputs.MaximumPatchSize + } + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_MAX_PATCH_SIZE: %d\n", maxPatchSize)) + // Add activation comment information if available (for updating the comment with PR link) + if data.AIReaction != "" && data.AIReaction != "none" { + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_COMMENT_ID: ${{ needs.%s.outputs.comment_id }}\n", constants.ActivationJobName)) + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_COMMENT_REPO: ${{ needs.%s.outputs.comment_repo }}\n", constants.ActivationJobName)) + } + // Add expires value if set (only for same-repo PRs - when target-repo is not set) + if cfg.Expires > 0 && cfg.TargetRepoSlug == "" { + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_PR_EXPIRES: \"%d\"\n", cfg.Expires)) + } + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, cfg.TargetRepoSlug)...) + + condition := BuildSafeOutputType("create_pull_request") + + // Build pre-steps for checkout and git config + preSteps := c.buildCreatePullRequestPreStepsConsolidated(data, cfg, condition) + + return SafeOutputStepConfig{ + StepName: "Create Pull Request", + StepID: "create_pull_request", + ScriptName: "create_pull_request", + Script: getCreatePullRequestScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + PreSteps: preSteps, + } +} + +// buildUpdatePullRequestStepConfig builds the configuration for updating a pull request +func (c *Compiler) buildUpdatePullRequestStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.UpdatePullRequests + + var customEnvVars []string + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, cfg.TargetRepoSlug)...) + + condition := BuildSafeOutputType("update_pull_request") + + return SafeOutputStepConfig{ + StepName: "Update Pull Request", + StepID: "update_pull_request", + ScriptName: "update_pull_request", + Script: getUpdatePullRequestScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} + +// buildClosePullRequestStepConfig builds the configuration for closing a pull request +func (c *Compiler) buildClosePullRequestStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.ClosePullRequests + + var customEnvVars []string + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("close_pull_request") + + return SafeOutputStepConfig{ + StepName: "Close Pull Request", + StepID: "close_pull_request", + ScriptName: "close_pull_request", + Script: getClosePullRequestScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} + +// buildCreatePRReviewCommentStepConfig builds the configuration for creating a PR review comment +func (c *Compiler) buildCreatePRReviewCommentStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.CreatePullRequestReviewComments + + var customEnvVars []string + // Add side configuration + if cfg.Side != "" { + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_PR_REVIEW_COMMENT_SIDE: %q\n", cfg.Side)) + } + // Add target configuration + if cfg.Target != "" { + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_PR_REVIEW_COMMENT_TARGET: %q\n", cfg.Target)) + } + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("create_pull_request_review_comment") + + return SafeOutputStepConfig{ + StepName: "Create PR Review Comment", + StepID: "create_pr_review_comment", + ScriptName: "create_pr_review_comment", + Script: getCreatePRReviewCommentScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} + +// buildPushToPullRequestBranchStepConfig builds the configuration for pushing to a pull request branch +func (c *Compiler) buildPushToPullRequestBranchStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.PushToPullRequestBranch + + var customEnvVars []string + // Add target config if set + if cfg.Target != "" { + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_PUSH_TARGET: %q\n", cfg.Target)) + } + // Add if-no-changes config if set + if cfg.IfNoChanges != "" { + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_PUSH_IF_NO_CHANGES: %q\n", cfg.IfNoChanges)) + } + // Add title prefix if set (using same env var as create-pull-request) + customEnvVars = append(customEnvVars, buildTitlePrefixEnvVar("GH_AW_PR_TITLE_PREFIX", cfg.TitlePrefix)...) + // Add labels if set + customEnvVars = append(customEnvVars, buildLabelsEnvVar("GH_AW_PR_LABELS", cfg.Labels)...) + // Add commit title suffix if set + if cfg.CommitTitleSuffix != "" { + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_COMMIT_TITLE_SUFFIX: %q\n", cfg.CommitTitleSuffix)) + } + // Add max patch size setting + maxPatchSize := 1024 // default 1024 KB + if data.SafeOutputs.MaximumPatchSize > 0 { + maxPatchSize = data.SafeOutputs.MaximumPatchSize + } + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_MAX_PATCH_SIZE: %d\n", maxPatchSize)) + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("push_to_pull_request_branch") + + // Build pre-steps for checkout and git config + preSteps := c.buildPushToPullRequestBranchPreStepsConsolidated(data, cfg, condition) + + return SafeOutputStepConfig{ + StepName: "Push To Pull Request Branch", + StepID: "push_to_pull_request_branch", + ScriptName: "push_to_pull_request_branch", + Script: getPushToPullRequestBranchScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + PreSteps: preSteps, + } +} + +// buildAddReviewerStepConfig builds the configuration for adding a reviewer +func (c *Compiler) buildAddReviewerStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.AddReviewer + + var customEnvVars []string + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("add_reviewer") + + return SafeOutputStepConfig{ + StepName: "Add Reviewer", + StepID: "add_reviewer", + ScriptName: "add_reviewer", + Script: getAddReviewerScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} + +// buildCreatePullRequestPreStepsConsolidated builds the pre-steps for create-pull-request +// in the consolidated safe outputs job +func (c *Compiler) buildCreatePullRequestPreStepsConsolidated(data *WorkflowData, cfg *CreatePullRequestsConfig, condition ConditionNode) []string { + var preSteps []string + + // Determine which token to use for checkout + // If an app is configured, use the app token; otherwise use the default github.token + var checkoutToken string + var gitRemoteToken string + if data.SafeOutputs.App != nil { + checkoutToken = "${{ steps.app-token.outputs.token }}" + gitRemoteToken = "${{ steps.app-token.outputs.token }}" + } else { + checkoutToken = "${{ github.token }}" + gitRemoteToken = "${{ github.token }}" + } + + // Step 1: Checkout repository with conditional execution + preSteps = append(preSteps, " - name: Checkout repository\n") + // Add the condition to only checkout if create_pull_request will run + preSteps = append(preSteps, fmt.Sprintf(" if: %s\n", condition.Render())) + preSteps = append(preSteps, fmt.Sprintf(" uses: %s\n", GetActionPin("actions/checkout"))) + preSteps = append(preSteps, " with:\n") + preSteps = append(preSteps, fmt.Sprintf(" token: %s\n", checkoutToken)) + preSteps = append(preSteps, " persist-credentials: false\n") + preSteps = append(preSteps, " fetch-depth: 1\n") + if c.trialMode { + if c.trialLogicalRepoSlug != "" { + preSteps = append(preSteps, fmt.Sprintf(" repository: %s\n", c.trialLogicalRepoSlug)) + } + } + + // Step 2: Configure Git credentials with conditional execution + gitConfigSteps := []string{ + " - name: Configure Git credentials\n", + fmt.Sprintf(" if: %s\n", condition.Render()), + " env:\n", + " REPO_NAME: ${{ github.repository }}\n", + " SERVER_URL: ${{ github.server_url }}\n", + " run: |\n", + " git config --global user.email \"github-actions[bot]@users.noreply.github.com\"\n", + " git config --global user.name \"github-actions[bot]\"\n", + " # Re-authenticate git with GitHub token\n", + " SERVER_URL_STRIPPED=\"${SERVER_URL#https://}\"\n", + fmt.Sprintf(" git remote set-url origin \"https://x-access-token:%s@${SERVER_URL_STRIPPED}/${REPO_NAME}.git\"\n", gitRemoteToken), + " echo \"Git configured with standard GitHub Actions identity\"\n", + } + preSteps = append(preSteps, gitConfigSteps...) + + return preSteps +} + +// buildPushToPullRequestBranchPreStepsConsolidated builds the pre-steps for push-to-pull-request-branch +// in the consolidated safe outputs job +func (c *Compiler) buildPushToPullRequestBranchPreStepsConsolidated(data *WorkflowData, cfg *PushToPullRequestBranchConfig, condition ConditionNode) []string { + var preSteps []string + + // Determine which token to use for checkout + // If an app is configured, use the app token; otherwise use the default github.token + var checkoutToken string + var gitRemoteToken string + if data.SafeOutputs.App != nil { + checkoutToken = "${{ steps.app-token.outputs.token }}" + gitRemoteToken = "${{ steps.app-token.outputs.token }}" + } else { + checkoutToken = "${{ github.token }}" + gitRemoteToken = "${{ github.token }}" + } + + // Step 1: Checkout repository with conditional execution + preSteps = append(preSteps, " - name: Checkout repository\n") + // Add the condition to only checkout if push_to_pull_request_branch will run + preSteps = append(preSteps, fmt.Sprintf(" if: %s\n", condition.Render())) + preSteps = append(preSteps, fmt.Sprintf(" uses: %s\n", GetActionPin("actions/checkout"))) + preSteps = append(preSteps, " with:\n") + preSteps = append(preSteps, fmt.Sprintf(" token: %s\n", checkoutToken)) + preSteps = append(preSteps, " persist-credentials: false\n") + preSteps = append(preSteps, " fetch-depth: 1\n") + if c.trialMode { + if c.trialLogicalRepoSlug != "" { + preSteps = append(preSteps, fmt.Sprintf(" repository: %s\n", c.trialLogicalRepoSlug)) + } + } + + // Step 2: Configure Git credentials with conditional execution + gitConfigSteps := []string{ + " - name: Configure Git credentials\n", + fmt.Sprintf(" if: %s\n", condition.Render()), + " env:\n", + " REPO_NAME: ${{ github.repository }}\n", + " SERVER_URL: ${{ github.server_url }}\n", + " run: |\n", + " git config --global user.email \"github-actions[bot]@users.noreply.github.com\"\n", + " git config --global user.name \"github-actions[bot]\"\n", + " # Re-authenticate git with GitHub token\n", + " SERVER_URL_STRIPPED=\"${SERVER_URL#https://}\"\n", + fmt.Sprintf(" git remote set-url origin \"https://x-access-token:%s@${SERVER_URL_STRIPPED}/${REPO_NAME}.git\"\n", gitRemoteToken), + " echo \"Git configured with standard GitHub Actions identity\"\n", + } + preSteps = append(preSteps, gitConfigSteps...) + + return preSteps +} diff --git a/pkg/workflow/compiler_safe_outputs_shared.go b/pkg/workflow/compiler_safe_outputs_shared.go new file mode 100644 index 0000000000..3651364d72 --- /dev/null +++ b/pkg/workflow/compiler_safe_outputs_shared.go @@ -0,0 +1,115 @@ +package workflow + +import "fmt" + +// buildAddCommentStepConfig builds the configuration for adding a comment +// This works across multiple entity types (issues, PRs, discussions) +func (c *Compiler) buildAddCommentStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool, createIssueEnabled, createDiscussionEnabled, createPullRequestEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.AddComments + + var customEnvVars []string + if cfg.Target != "" { + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_COMMENT_TARGET: %q\n", cfg.Target)) + } + if cfg.Discussion != nil && *cfg.Discussion { + customEnvVars = append(customEnvVars, " GITHUB_AW_COMMENT_DISCUSSION: \"true\"\n") + } + if cfg.HideOlderComments { + customEnvVars = append(customEnvVars, " GH_AW_HIDE_OLDER_COMMENTS: \"true\"\n") + } + + // Reference outputs from earlier steps in the same job + if createIssueEnabled { + customEnvVars = append(customEnvVars, " GH_AW_CREATED_ISSUE_URL: ${{ steps.create_issue.outputs.issue_url }}\n") + customEnvVars = append(customEnvVars, " GH_AW_CREATED_ISSUE_NUMBER: ${{ steps.create_issue.outputs.issue_number }}\n") + customEnvVars = append(customEnvVars, " GH_AW_TEMPORARY_ID_MAP: ${{ steps.create_issue.outputs.temporary_id_map }}\n") + } + if createDiscussionEnabled { + customEnvVars = append(customEnvVars, " GH_AW_CREATED_DISCUSSION_URL: ${{ steps.create_discussion.outputs.discussion_url }}\n") + customEnvVars = append(customEnvVars, " GH_AW_CREATED_DISCUSSION_NUMBER: ${{ steps.create_discussion.outputs.discussion_number }}\n") + } + if createPullRequestEnabled { + customEnvVars = append(customEnvVars, " GH_AW_CREATED_PULL_REQUEST_URL: ${{ steps.create_pull_request.outputs.pull_request_url }}\n") + customEnvVars = append(customEnvVars, " GH_AW_CREATED_PULL_REQUEST_NUMBER: ${{ steps.create_pull_request.outputs.pull_request_number }}\n") + } + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, cfg.TargetRepoSlug)...) + + condition := BuildSafeOutputType("add_comment") + + return SafeOutputStepConfig{ + StepName: "Add Comment", + StepID: "add_comment", + ScriptName: "add_comment", + Script: getAddCommentScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} + +// buildAddLabelsStepConfig builds the configuration for adding labels +func (c *Compiler) buildAddLabelsStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.AddLabels + + var customEnvVars []string + customEnvVars = append(customEnvVars, buildLabelsEnvVar("GH_AW_LABELS_ALLOWED", cfg.Allowed)...) + if cfg.Max > 0 { + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_LABELS_MAX_COUNT: %d\n", cfg.Max)) + } + if cfg.Target != "" { + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_LABELS_TARGET: %q\n", cfg.Target)) + } + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, cfg.TargetRepoSlug)...) + + condition := BuildSafeOutputType("add_labels") + + return SafeOutputStepConfig{ + StepName: "Add Labels", + StepID: "add_labels", + ScriptName: "add_labels", + Script: getAddLabelsScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} + +// buildHideCommentStepConfig builds the configuration for hiding a comment +func (c *Compiler) buildHideCommentStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.HideComment + + var customEnvVars []string + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("hide_comment") + + return SafeOutputStepConfig{ + StepName: "Hide Comment", + StepID: "hide_comment", + ScriptName: "hide_comment", + Script: getHideCommentScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} + +// buildUploadAssetsStepConfig builds the configuration for uploading assets +func (c *Compiler) buildUploadAssetsStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.UploadAssets + + var customEnvVars []string + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("upload_asset") + + return SafeOutputStepConfig{ + StepName: "Upload Assets", + StepID: "upload_assets", + ScriptName: "upload_assets", + Script: getUploadAssetsScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} diff --git a/pkg/workflow/compiler_safe_outputs_specialized.go b/pkg/workflow/compiler_safe_outputs_specialized.go new file mode 100644 index 0000000000..dd0e2a0de8 --- /dev/null +++ b/pkg/workflow/compiler_safe_outputs_specialized.go @@ -0,0 +1,145 @@ +package workflow + +import "fmt" + +// buildCreateCodeScanningAlertStepConfig builds the configuration for creating a code scanning alert +func (c *Compiler) buildCreateCodeScanningAlertStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool, workflowFilename string) SafeOutputStepConfig { + cfg := data.SafeOutputs.CreateCodeScanningAlerts + + var customEnvVars []string + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_WORKFLOW_FILENAME: %q\n", workflowFilename)) + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("create_code_scanning_alert") + + return SafeOutputStepConfig{ + StepName: "Create Code Scanning Alert", + StepID: "create_code_scanning_alert", + ScriptName: "create_code_scanning_alert", + Script: getCreateCodeScanningAlertScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} + +// buildAssignMilestoneStepConfig builds the configuration for assigning a milestone +func (c *Compiler) buildAssignMilestoneStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.AssignMilestone + + var customEnvVars []string + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("assign_milestone") + + return SafeOutputStepConfig{ + StepName: "Assign Milestone", + StepID: "assign_milestone", + ScriptName: "assign_milestone", + Script: getAssignMilestoneScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} + +// buildAssignToAgentStepConfig builds the configuration for assigning to an agent +func (c *Compiler) buildAssignToAgentStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.AssignToAgent + + var customEnvVars []string + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("assign_to_agent") + + return SafeOutputStepConfig{ + StepName: "Assign To Agent", + StepID: "assign_to_agent", + ScriptName: "assign_to_agent", + Script: getAssignToAgentScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + UseAgentToken: true, + } +} + +// buildAssignToUserStepConfig builds the configuration for assigning to a user +func (c *Compiler) buildAssignToUserStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.AssignToUser + + var customEnvVars []string + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("assign_to_user") + + return SafeOutputStepConfig{ + StepName: "Assign To User", + StepID: "assign_to_user", + ScriptName: "assign_to_user", + Script: getAssignToUserScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} + +// buildUpdateReleaseStepConfig builds the configuration for updating a release +func (c *Compiler) buildUpdateReleaseStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.UpdateRelease + + var customEnvVars []string + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("update_release") + + return SafeOutputStepConfig{ + StepName: "Update Release", + StepID: "update_release", + ScriptName: "update_release", + Script: getUpdateReleaseScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +} + +// buildCreateAgentTaskStepConfig builds the configuration for creating an agent task +func (c *Compiler) buildCreateAgentTaskStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.CreateAgentTasks + + var customEnvVars []string + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("create_agent_task") + + return SafeOutputStepConfig{ + StepName: "Create Agent Task", + StepID: "create_agent_task", + Script: createAgentTaskScript, + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + UseCopilotToken: true, + } +} + +// buildUpdateProjectStepConfig builds the configuration for updating a project +func (c *Compiler) buildUpdateProjectStepConfig(data *WorkflowData, mainJobName string, threatDetectionEnabled bool) SafeOutputStepConfig { + cfg := data.SafeOutputs.UpdateProjects + + var customEnvVars []string + customEnvVars = append(customEnvVars, c.buildStepLevelSafeOutputEnvVars(data, "")...) + + condition := BuildSafeOutputType("update_project") + + return SafeOutputStepConfig{ + StepName: "Update Project", + StepID: "update_project", + ScriptName: "update_project", + Script: getUpdateProjectScript(), + CustomEnvVars: customEnvVars, + Condition: condition, + Token: cfg.GitHubToken, + } +}