Skip to content

Commit

Permalink
[TASK] Automate updates from core
Browse files Browse the repository at this point in the history
This patch automates the updates from the TYPO3 Core by perdiodically
check for changes, commit it and create a pull request.

Resolves #15
  • Loading branch information
gilbertsoft committed Nov 15, 2021
1 parent a09e2b5 commit ea7acb8
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 21 deletions.
152 changes: 135 additions & 17 deletions build/dist/sync.js → .github/actions/dist/core-synchronization.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,46 @@
module.exports = async ({github, context, core, exec}) => {
// Nested functions, core.startGroup() MUST NOT be used

function debug(...data) {
/**
* Core synchronization action.
*
* @param {@actions/github/GitHub} github
* @param {@actions/github/Context} context
* @param {@actions/core} core
* @param {@actions/exec} exec
* @param {string} typo3CoreOwner
* @param {string} typo3CoreRepo
* @returns {void}
*/
module.exports = async ({github, context, core, exec}, typo3CoreOwner, typo3CoreRepo) => {
/**
* Log a debug message.
*
* core.debug does not recursively resolve all objects so instead we use the
* console.log which behalfs like expected.
*
* @param {...any} data
* @returns {void}
*/
function debug(
...data
) {
if (!core.isDebug()) {
return
}

console.log(...data)
}

/**
* Download a file from the core.
*
* @param {string} path
* @returns {string}
*/
async function getCoreFileContent(
path
) {
const response = await github.rest.repos.getContent({
owner: 'TYPO3',
repo: 'typo3',
owner: typo3CoreOwner,
repo: typo3CoreRepo,
path: path,
})

Expand All @@ -29,17 +55,37 @@ module.exports = async ({github, context, core, exec}) => {
return Buffer.from(response.data.content, 'base64').toString('utf8')
}

/**
* Extract rules from core's php-cs-fixer config.
*
* @param {string} content
* @param {RegExp} regex
* @returns {string}
*/
function getRules(
content,
regex
) {
const coreRulesMatches = regex.exec(content)

if (coreRulesMatches === null) {
debug(content)
throw new Error('Error while extracting rules.')
}

debug(`PHP Coding Standards Fixer rules extracted:\n\n${coreRulesMatches[1]}`)

return coreRulesMatches[1]
}

/**
* Replaces the rules in a local file by the provided ones.
*
* @param {string} path
* @param {RegExp} regex
* @param {string} coreRules
* @returns {boolean}
*/
function replaceRules(
path,
regex,
Expand All @@ -48,6 +94,11 @@ module.exports = async ({github, context, core, exec}) => {
const fs = require('fs')
const currentContent = fs.readFileSync(path, 'utf8')

if (regex.exec(currentContent) === null) {
debug(currentContent)
throw new Error('Error while replacing rules.')
}

const newContent = currentContent.replace(regex, '$1' + coreRules + '$2')

if (currentContent === newContent) {
Expand All @@ -61,6 +112,13 @@ module.exports = async ({github, context, core, exec}) => {
return true
}

/**
* Replaces the content of a file with a new one.
*
* @param {string} path
* @param {string} newContent
* @returns {boolean}
*/
function replaceFile(
path,
newContent
Expand All @@ -79,6 +137,14 @@ module.exports = async ({github, context, core, exec}) => {
return true
}

/**
* Executes a command and throws in case of a failure.
*
* @param {string} commandLine
* @param {string[]} args
* @param {ExecOptions} options
* @returns {void}
*/
async function safeExec(
commandLine,
args,
Expand All @@ -91,18 +157,37 @@ module.exports = async ({github, context, core, exec}) => {
}
}

/**
* Commits all changes with the given message.
*
* @param {string} message
* @returns {void}
*/
async function commitChange(
message
) {
safeExec(`git commit -a -m "${message}"`)
}

/**
* Pushes the active branch to the given remote branch.
*
* @param {string} branch
* @returns {void}
*/
async function pushChanges(
branch
) {
safeExec(`git push -f origin ${branch}`)
}

/**
* Lookups a pending pull request and returns its number or 0 if
* not found.
*
* @param {string} branch
* @returns {number}
*/
async function getPendingPullRequest(
branch
) {
Expand All @@ -129,6 +214,11 @@ module.exports = async ({github, context, core, exec}) => {
return pullRequestNo
}

/**
* Returns the default branch of the repository.
*
* @returns {string}
*/
async function getDefaultBranch() {
if (context.payload.repository.default_branch !== undefined) {
return context.payload.repository.default_branch
Expand All @@ -148,6 +238,12 @@ module.exports = async ({github, context, core, exec}) => {
return response.data.default_branch
}

/**
* Creates a pull request for the given branch and returns its number.
*
* @param {string} branch
* @returns {number}
*/
async function createPullRequest(
branch
) {
Expand All @@ -156,7 +252,7 @@ module.exports = async ({github, context, core, exec}) => {
repo: context.repo.repo,
title: "[TASK] Sync files with the latest TYPO3 Core version",
head: branch,
base: await getDefaultBranch(),
base: getDefaultBranch(),
body: `Test body.`,
})

Expand All @@ -171,9 +267,11 @@ module.exports = async ({github, context, core, exec}) => {
return response.data.number
}


// Top level functions, core.startGroup() MUST be used

/**
* Dumps the context if debug mode is enabled.
*
* @returns {void}
*/
function dumpContext() {
if (!core.isDebug()) {
return
Expand All @@ -188,6 +286,13 @@ module.exports = async ({github, context, core, exec}) => {
}
}

/**
* Setups the repository to be able to commit and switches to the
* given branch.
*
* @param {string} branch
* @returns {void}
*/
async function setupRepository(
branch
) {
Expand All @@ -203,6 +308,11 @@ module.exports = async ({github, context, core, exec}) => {
}
}

/**
* Synchronizes the php-cs-fixer rules with the core.
*
* @returns {boolean}
*/
async function syncPhpCsFixerRules() {
core.startGroup('Sync PHP Coding Standards Fixer rules with the latest TYPO3 Core version')

Expand All @@ -222,6 +332,11 @@ module.exports = async ({github, context, core, exec}) => {
}
}

/**
* Synchronizes the editorconfig with the core.
*
* @returns {boolean}
*/
async function syncEditorconfig() {
core.startGroup('Sync editorconfig with the latest TYPO3 Core version')

Expand All @@ -240,18 +355,18 @@ module.exports = async ({github, context, core, exec}) => {
}
}

/**
* Handles changes by pushing and creating a pull request.
*
* @param {string} branch
* @returns {boolean}
*/
async function handleChanges(
hasChanges,
branch
) {
core.startGroup(`Handle changes`)

try {
if (!hasChanges) {
core.info('No changes found.')
return 0
}

pushChanges(branch)

const pullRequestNo = await getPendingPullRequest(branch)
Expand All @@ -278,7 +393,10 @@ module.exports = async ({github, context, core, exec}) => {
const editorconfig = await syncEditorconfig()
core.setOutput('editorconfig', editorconfig)

const pullRequestNo = await handleChanges(phpCsFixer || editorconfig, branch)
let pullRequestNo = 0
if (phpCsFixer || editorconfig) {
pullRequestNo = await handleChanges(branch)
}

core.setOutput('pull-request', pullRequestNo)
} catch (err) {
Expand Down
7 changes: 3 additions & 4 deletions .github/workflows/core-synchronization.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ jobs:
fetch-depth: 0

- name: Sync files with the latest TYPO3 Core version
id: sync-rules
id: core-synchronization
uses: actions/github-script@v5
with:
github-token: ${{secrets.GITHUB_TOKEN}}
debug: ${{ secrets.ACTIONS_DEBUG == 'true' }}
script: |
const script = require('./build/dist/sync.js')
await script({github, context, core, exec})
const script = require('./.github/actions/dist/core-synchronization.js')
await script({github, context, core, exec}, 'TYPO3', 'typo3')

0 comments on commit ea7acb8

Please sign in to comment.