Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions .github/scripts/create-pr-comment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
const appFn = require('./index.js')
const { createProbot } = require('probot')
const Settings = require('./lib/settings')
const ConfigManager = require('./lib/configManager')
const fs = require('fs')
const path = require('path')
const yaml = require('js-yaml')
const env = require('./lib/env')

async function syncWithPRComment() {
try {
// Read PR event data from GitHub Actions
const eventPath = process.env.GITHUB_EVENT_PATH
if (!eventPath) {
throw new Error('GITHUB_EVENT_PATH environment variable not found')
}

const event = JSON.parse(fs.readFileSync(eventPath, 'utf8'))

if (!event.pull_request) {
throw new Error('No pull request found in event payload')
}

// Initialize Probot
const probot = createProbot()

// Get installation ID from organization
probot.log.info('Fetching installations...')
const authGithub = await probot.auth()
const installations = await authGithub.paginate(
authGithub.apps.listInstallations.endpoint.merge({ per_page: 100 })
)

if (installations.length === 0) {
throw new Error('No installations found')
}

const installation = installations[0]
probot.log.info(`Found installation: ${installation.id}`)

// Authenticate as the installation
const github = await probot.auth(installation.id)

// Construct repository object
const repo = {
repo: process.env.ADMIN_REPO || '.github',
owner: installation.account.login
}

// Construct synthetic context with fake check_run structure
// This mimics the webhook event structure that handleResults expects
const context = {
payload: {
installation,
repository: {
owner: { login: event.repository.owner.login },
name: event.repository.name
},
// This is the critical part - handleResults looks for this structure
check_run: {
id: 0, // Dummy ID - handleResults will try to update check run, but we'll ignore errors
check_suite: {
pull_requests: [{
number: event.pull_request.number
}]
}
}
},
octokit: github,
log: probot.log,
repo: () => repo
}

probot.log.info(`Starting sync for PR #${event.pull_request.number} in NOP mode`)

// Load deployment config (same logic as syncAllSettings)
let deploymentConfig = {}
if (env.DEPLOYMENT_CONFIG_FILE && fs.existsSync(env.DEPLOYMENT_CONFIG_FILE)) {
deploymentConfig = yaml.load(fs.readFileSync(env.DEPLOYMENT_CONFIG_FILE, 'utf8'))
}

// Load global settings using ConfigManager
// ConfigManager expects (context, ref) - context needs to have repo() function
const configManager = new ConfigManager(context, event.pull_request.head.ref)
const repoSettings = await configManager.loadGlobalSettingsYaml()

// Merge configs
const runtimeConfig = { restrictedRepos: ['admin', '.github', 'safe-settings'], ...repoSettings }
const config = { ...runtimeConfig, ...deploymentConfig }

// Call Settings.syncAll directly with NOP mode = true
// This will automatically call handleResults which will post the PR comment
try {
await Settings.syncAll(true, context, repo, config, event.pull_request.head.ref)
probot.log.info('Sync completed successfully')
} catch (syncError) {
// Check if the error is about check run update (expected since we don't have a real check run)
const isCheckRunError =
(syncError.request && syncError.request.url && syncError.request.url.includes('check-runs')) ||
(syncError.message && syncError.message.includes('check-runs')) ||
(syncError.status === 404 && syncError.request && syncError.request.method === 'PATCH')

if (isCheckRunError) {
probot.log.info('PR comment posted successfully (check run update failed as expected)')
// Exit successfully since the PR comment was posted
} else {
// Re-throw other errors
throw syncError
}
}
} catch (error) {
console.error('Error during sync:', error)
process.exit(1)
}
}

syncWithPRComment()
56 changes: 56 additions & 0 deletions .github/workflows/safe-settings-pr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Safe Settings Sync PR
on:
pull_request:
paths:
- safe-settings/**
- .github/workflows/safe-settings.yaml

concurrency:
cancel-in-progress: true
group: >-
${{ github.workflow }}-${{ github.event.pull_request.number }}

jobs:
safeSettingsSync:
runs-on: ubuntu-latest
env:
# Version/tag of github/safe-settings repo to use:
SAFE_SETTINGS_VERSION: 2.1.17

# Path on GHA runner box where safe-settings code downloaded to:
SAFE_SETTINGS_CODE_DIR: .safe-settings-code
steps:
- uses: actions/checkout@v4

# Checkout of safe-settings repo for running full sync:
- uses: actions/checkout@v4
with:
repository: github/safe-settings
ref: ${{ env.SAFE_SETTINGS_VERSION }}
path: ${{ env.SAFE_SETTINGS_CODE_DIR }}
- uses: actions/setup-node@v6
with:
cache: 'npm'
node-version-file: ${{ env.SAFE_SETTINGS_CODE_DIR }}/.nvmrc
cache-dependency-path: |
${{ env.SAFE_SETTINGS_CODE_DIR }}/package-lock.json
- run: npm install
working-directory: ${{ env.SAFE_SETTINGS_CODE_DIR }}

- name: Copy PR comment script to safe-settings directory
run: cp .github/scripts/create-pr-comment.js ${{ env.SAFE_SETTINGS_CODE_DIR }}/

- name: Run sync with PR comment
run: node create-pr-comment.js
working-directory: ${{ env.SAFE_SETTINGS_CODE_DIR }}
env:
GH_ORG: healingpaper-solution
BLOCK_REPO_RENAME_BY_HUMAN: false
APP_ID: ${{ vars.SAFE_SETTINGS_APP_ID }}
PRIVATE_KEY: ${{ secrets.SAFE_SETTINGS_PRIVATE_KEY }}
GITHUB_CLIENT_ID: ${{ vars.SAFE_SETTINGS_GITHUB_CLIENT_ID }}
GITHUB_CLIENT_SECRET: ${{ secrets.SAFE_SETTINGS_GITHUB_CLIENT_SECRET }}
ADMIN_REPO: .github
CONFIG_PATH: safe-settings
CREATE_PR_COMMENT: true
DEPLOYMENT_CONFIG_FILE: safe-settings/deployment-settings.yml
6 changes: 1 addition & 5 deletions .github/workflows/safe-settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,11 @@ on:
push:
branches:
- main
pull_request:
paths:
- safe-settings/**
- .github/workflows/safe-settings.yaml

concurrency:
cancel-in-progress: true
group: >-
${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
${{ github.workflow }}-${{ github.ref }}

jobs:
safeSettingsSync:
Expand Down
2 changes: 1 addition & 1 deletion safe-settings/repos/connect-auth-module.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ repository:
allow_rebase_merge: true

# Either `true` to allow auto-merge on pull requests, or `false` to disallow auto-merge.
allow_auto_merge: false
allow_auto_merge: true

# Either `true` to always allow a pull request head branch that is behind its base
# branch to be updated even if it is not required to be up to date before merging,
Expand Down