diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml index a7d2f1f94be..934a784bcd6 100644 --- a/.github/workflows/changeset.lock.yml +++ b/.github/workflows/changeset.lock.yml @@ -77,20 +77,68 @@ jobs: text: ${{ steps.compute-text.outputs.text }} steps: - name: Check workflow file timestamps - run: | - WORKFLOW_FILE="${GITHUB_WORKSPACE}/.github/workflows/$(basename "$GITHUB_WORKFLOW" .lock.yml).md" - LOCK_FILE="${GITHUB_WORKSPACE}/.github/workflows/$GITHUB_WORKFLOW" - - if [ -f "$WORKFLOW_FILE" ] && [ -f "$LOCK_FILE" ]; then - if [ "$WORKFLOW_FILE" -nt "$LOCK_FILE" ]; then - echo "🔴🔴🔴 WARNING: Lock file '$LOCK_FILE' is outdated! The workflow file '$WORKFLOW_FILE' has been modified more recently. Run 'gh aw compile' to regenerate the lock file." >&2 - echo "## ⚠️ Workflow Lock File Warning" >> $GITHUB_STEP_SUMMARY - echo "🔴🔴🔴 **WARNING**: Lock file \`$LOCK_FILE\` is outdated!" >> $GITHUB_STEP_SUMMARY - echo "The workflow file \`$WORKFLOW_FILE\` has been modified more recently." >> $GITHUB_STEP_SUMMARY - echo "Run \`gh aw compile\` to regenerate the lock file." >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - fi - fi + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd + with: + script: | + const fs = require("fs"); + const path = require("path"); + async function main() { + const workspace = process.env.GITHUB_WORKSPACE; + const workflow = process.env.GITHUB_WORKFLOW; + if (!workspace) { + core.setFailed("Configuration error: GITHUB_WORKSPACE not available."); + return; + } + if (!workflow) { + core.setFailed("Configuration error: GITHUB_WORKFLOW not available."); + return; + } + const workflowBasename = path.basename(workflow, ".lock.yml"); + const workflowFile = path.join(workspace, ".github", "workflows", `${workflowBasename}.md`); + const lockFile = path.join(workspace, ".github", "workflows", workflow); + core.info(`Checking workflow timestamps:`); + core.info(` Source: ${workflowFile}`); + core.info(` Lock file: ${lockFile}`); + let workflowExists = false; + let lockExists = false; + try { + fs.accessSync(workflowFile, fs.constants.F_OK); + workflowExists = true; + } catch (error) { + core.info(`Source file does not exist: ${workflowFile}`); + } + try { + fs.accessSync(lockFile, fs.constants.F_OK); + lockExists = true; + } catch (error) { + core.info(`Lock file does not exist: ${lockFile}`); + } + if (!workflowExists || !lockExists) { + core.info("Skipping timestamp check - one or both files not found"); + return; + } + const workflowStat = fs.statSync(workflowFile); + const lockStat = fs.statSync(lockFile); + const workflowMtime = workflowStat.mtime.getTime(); + const lockMtime = lockStat.mtime.getTime(); + core.info(` Source modified: ${workflowStat.mtime.toISOString()}`); + core.info(` Lock modified: ${lockStat.mtime.toISOString()}`); + if (workflowMtime > lockMtime) { + const warningMessage = `🔴🔴🔴 WARNING: Lock file '${lockFile}' is outdated! The workflow file '${workflowFile}' has been modified more recently. Run 'gh aw compile' to regenerate the lock file.`; + core.error(warningMessage); + await core.summary + .addRaw("## ⚠️ Workflow Lock File Warning\n\n") + .addRaw(`🔴🔴🔴 **WARNING**: Lock file \`${lockFile}\` is outdated!\n\n`) + .addRaw(`The workflow file \`${workflowFile}\` has been modified more recently.\n\n`) + .addRaw("Run `gh aw compile` to regenerate the lock file.\n\n") + .write(); + } else { + core.info("✅ Lock file is up to date"); + } + } + main().catch(error => { + core.setFailed(error instanceof Error ? error.message : String(error)); + }); - name: Compute current body text id: compute-text uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000000..baf4101a4ae --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,47 @@ +name: CodeQL Security Analysis + +on: + schedule: + # Run daily at 6:00 AM UTC + - cron: '0 6 * * *' + workflow_dispatch: + +permissions: + actions: read + contents: read + security-events: write + +jobs: + analyze: + name: Analyze Code + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + language: ['go', 'javascript'] + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + queries: security-and-quality + + - name: Set up Go + if: matrix.language == 'go' + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + + - name: Build Go code + if: matrix.language == 'go' + run: make build + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{ matrix.language }}"