From 0509fc2f59813617b7b29331d691d080055cca7d Mon Sep 17 00:00:00 2001 From: Vicente Canales <1157901+vcanales@users.noreply.github.com> Date: Sat, 27 Apr 2024 19:38:22 -0500 Subject: [PATCH] Workflow security issue (#7778) * split workflow; checkout create-preview-links from trunk * split changed themes by , * revert test values --- .github/scripts/create-preview-links.js | 63 +++++-------------------- .github/workflows/preview-theme.yml | 47 +++++++++++++++--- adventurer/patterns/404.php | 1 + 3 files changed, 54 insertions(+), 57 deletions(-) diff --git a/.github/scripts/create-preview-links.js b/.github/scripts/create-preview-links.js index 8bda060282..143b320086 100644 --- a/.github/scripts/create-preview-links.js +++ b/.github/scripts/create-preview-links.js @@ -1,5 +1,3 @@ -const fs = require('fs'); - /* * This function creates a WordPress Playground blueprint JSON string for a theme. * @@ -32,39 +30,6 @@ function createBlueprint(themeSlug, branch) { return JSON.stringify(template); } -/* - * This function reads the `style.css` file of a theme and returns the theme name. - * - * @param {string} themeSlug - The slug of the theme to get the name of. - * @returns {string} - The name of the theme as defined in the `style.css` file. - */ -function getThemeName(themeSlug) { - const styleCss = fs.readFileSync(`${themeSlug}/style.css`, 'utf8'); - const themeName = styleCss.match(/Theme Name:(.*)/i)[1].trim(); - return themeName; -} - -/* - * This function reads the `style.css` file of a theme and returns the name of the parent theme. - * If the theme is not a child theme, it returns an empty string. - * - * @param {string} themeSlug - The slug of the theme to get the parent theme name of. - * @returns {string} - The name of the parent theme as defined in the `style.css` file. - */ -function getParentThemeName(themeSlug) { - const styleCss = fs.readFileSync(`${themeSlug}/style.css`, 'utf8'); - const parentTheme = styleCss.match(/Template:(.*)/i); - const isChildTheme = parentTheme && '' !== parentTheme[1].trim(); - - if (!isChildTheme) { - return ''; - } - - return parentTheme && '' !== parentTheme[1].trim() - ? parentTheme[1].trim() - : ''; -} - /* * This function creates a comment on a PR with preview links for the changed themes. * It is used by `preview-theme` workflow. @@ -74,30 +39,28 @@ function getParentThemeName(themeSlug) { * @param {string} changedThemeSlugs - A space-separated string of theme slugs that have changed. */ async function createPreviewLinksComment(github, context, changedThemeSlugs) { - const changedThemes = changedThemeSlugs.split(' '); + const changedThemes = changedThemeSlugs.split(','); const previewLinks = changedThemes - .map((themeSlug) => { - const parentThemeName = getParentThemeName(themeSlug); - const note = parentThemeName - ? ` (child theme of **${parentThemeName}**)` - : ''; - - return `- [Preview changes for **${getThemeName( - themeSlug - )}**](https://playground.wordpress.net/#${createBlueprint( + .map((theme) => { + const [themeName, themeDir] = theme.split(':'); + const themeSlug = themeDir.split('/')[0]; + const parentThemeSlug = themeName.split('_childof_')[1]; + return `- [Preview changes for **${ + themeName.split('_childof_')[0] + }**](https://playground.wordpress.net/#${createBlueprint( themeSlug, context.payload.pull_request.head.ref - )})${note}`; + )})${parentThemeSlug ? ` (child of **${parentThemeSlug}**)` : ''}`; }) .join('\n'); - const includesChildThemes = changedThemes.some( - (themeSlug) => '' !== getParentThemeName(themeSlug) - ); + const includesChildThemes = previewLinks.includes('child of'); const comment = ` I've detected changes to the following themes in this PR: ${changedThemes - .map((themeSlug) => getThemeName(themeSlug)) + .map( + (changedThemes) => changedThemes.split(':')[0].split('_childof_')[0] + ) .join(', ')}. You can preview these changes by following the links below: diff --git a/.github/workflows/preview-theme.yml b/.github/workflows/preview-theme.yml index fc35b2d1ce..30b07ab054 100644 --- a/.github/workflows/preview-theme.yml +++ b/.github/workflows/preview-theme.yml @@ -3,10 +3,15 @@ name: Preview Theme Changes on: pull_request_target: types: [opened, synchronize] +permissions: + pull-requests: write jobs: check-for-changes-to-themes: runs-on: ubuntu-latest + outputs: + HAS_THEME_CHANGES: ${{ steps.check-for-changes.outputs.HAS_THEME_CHANGES }} + CHANGED_THEMES: ${{ steps.check-for-changes.outputs.CHANGED_THEMES }} steps: - name: Checkout uses: actions/checkout@v2 @@ -25,9 +30,14 @@ jobs: for file in $changed_files; do dir_name=$(dirname "$file") while [[ "$dir_name" != "." ]]; do - if [[ -f "$dir_name/style.css" ]]; then # Check if the parent directory contains a theme - # Save only the basename - unique_dirs[$dir_name]=$(basename $dir_name) + if [[ -f "$dir_name/style.css" ]]; then + # Get theme name from style.css + theme_name=$(grep -m 1 "Theme Name:" "$dir_name/style.css" | sed 's/Theme Name: //') + parent_theme=$(grep -m 1 "Template:" "$dir_name/style.css" | sed 's/Template: //') + # Append parent theme to the theme name if it exists + [ -n "$parent_theme" ] && theme_name="${theme_name}_childof_${parent_theme}" + # Store theme name and directory in associative array + unique_dirs["$theme_name"]=$dir_name break fi dir_name=$(dirname "$dir_name") @@ -41,13 +51,36 @@ jobs: fi # Output list of theme slugs with changes echo "HAS_THEME_CHANGES=true" >> $GITHUB_OUTPUT - echo "CHANGED_THEMES=$(echo ${unique_dirs[@]})" >> $GITHUB_ENV + + # Serialize associative array of theme dirs to a string + declare -A CHANGED_THEMES + for theme in "${!unique_dirs[@]}"; do + # Append each entry as key:value, + CHANGED_THEMES+="$theme:${unique_dirs[$theme]}," + done + # Remove the last comma for correct JSON formatting + CHANGED_THEMES=${CHANGED_THEMES%,} + echo "CHANGED_THEMES=$CHANGED_THEMES" >> $GITHUB_OUTPUT + echo "Theme directories with changes: $CHANGED_THEMES" + + handle-pr-comment: + runs-on: ubuntu-latest + needs: check-for-changes-to-themes + steps: + - name: Checkout create-preview-links script from trunk + uses: actions/checkout@v3 + with: + repository: Automattic/themes + sparse-checkout: .github/scripts/create-preview-links + ref: trunk - name: Add Preview Links comment id: comment-on-pr - if: ${{ steps.check-for-changes.outputs.HAS_THEME_CHANGES == 'true' }} + if: ${{ needs.check-for-changes-to-themes.outputs.HAS_THEME_CHANGES == 'true' }} uses: actions/github-script@v7 + env: + CHANGED_THEMES: ${{ needs.check-for-changes-to-themes.outputs.CHANGED_THEMES }} with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | @@ -55,7 +88,7 @@ jobs: createPreviewLinks(github, context, process.env.CHANGED_THEMES); - name: Remove comment if no changes are detected - if: ${{ steps.check-for-changes.outputs.HAS_THEME_CHANGES == 'false' }} + if: ${{ needs.check-for-changes-to-themes.outputs.HAS_THEME_CHANGES == 'false' }} uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} @@ -75,4 +108,4 @@ jobs: repo: context.repo.repo }); } - \ No newline at end of file + \ No newline at end of file diff --git a/adventurer/patterns/404.php b/adventurer/patterns/404.php index 5e8f9231e8..696d486ff1 100644 --- a/adventurer/patterns/404.php +++ b/adventurer/patterns/404.php @@ -13,6 +13,7 @@

+