diff --git a/.github/fetch_icons/action.yml b/.github/fetch_icons/action.yml index 2034b540..2dc57b25 100644 --- a/.github/fetch_icons/action.yml +++ b/.github/fetch_icons/action.yml @@ -10,11 +10,11 @@ inputs: actions-runner-debug: description: "The date and time the action was run" required: false - default: false - type: boolean + default: "false" +# type: boolean outputs: files_changed: - description: "Boolean that gets set to true if any icons have been added or removed" + description: "Array of files if any icons have been added or removed. If this length > 0, the PR should be created." runs: using: "node20" main: "index.js" diff --git a/.github/fetch_icons/index.js b/.github/fetch_icons/index.js index 9258b79f..38ca3b1f 100644 --- a/.github/fetch_icons/index.js +++ b/.github/fetch_icons/index.js @@ -26,21 +26,29 @@ try { "outputs", VERBOSE_LOGS, ); - let filesChanged = false; + let filesChanged = []; if (newHash) { writeFileSync(hashPath, newHash); filesChanged = checkForFileChanges(VERBOSE_LOGS); - if (filesChanged) { + if (filesChanged.length > 0) { const packageJson = JSON.parse(readFileSync("./package.json").toString()); packageJson.lastUpdated = DATE; writeFileSync("./package.json", JSON.stringify(packageJson, null, 2)); stageAllFiles(); } } + const filesChangedOutput = Object.entries(filesChanged.reduce((acc, {type, path}) => { + const descriptiveChangeType = gitChangeTypeToString(type); + if(acc[descriptiveChangeType] == undefined) { + acc.descriptiveChangeType = []; + } + acc.descriptiveChangeType.push(` ${path}`); + return acc; + }, [])).map(([key, value]) => `${key}:\n${value.join("\n")}`).join("\n\n"); console.log("Files changed", filesChanged); - core.setOutput("files_changed", filesChanged); + core.setOutput("files_changed", filesChangedOutput); } catch (error) { core.setFailed(error.message); } diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ab6b4a64..ab90a222 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -52,10 +52,10 @@ jobs: - name: Icons changed run: echo ${{ steps.fetch_icons.outputs.files_changed }} - name: Create code connect files - if: ${{ steps.fetch_icons.outputs.files_changed == 'true'}} + if: ${{ steps.fetch_icons.outputs.files_changed != ''}} uses: ./.github/create_code_connect - name: Create PR title - if: ${{ steps.fetch_icons.outputs.files_changed == 'true'}} + if: ${{ steps.fetch_icons.outputs.files_changed != ''}} id: title run: | if [ ${{github.ref_name=='main'}} ]; then @@ -63,9 +63,11 @@ jobs: else TITLE='chore: Icon updates ${{ steps.date.outputs.date }}(${{github.ref_name}})' fi + BODY='${{ steps.fetch_icons.outputs.files_changed }}' echo "TITLE=$TITLE" >> $GITHUB_OUTPUT + echo "BODY=$BODY" >> $GITHUB_OUTPUT - name: Push - if: ${{ steps.fetch_icons.outputs.files_changed == 'true'}} + if: ${{ steps.fetch_icons.outputs.files_changed != ''}} run: | git checkout -b ${{steps.branch_name.outputs.BRANCH_NAME}} git config --global user.name "zeta-icons-bot" @@ -74,12 +76,12 @@ jobs: git commit -m "${{steps.title.outputs.TITLE}}" git push --set-upstream origin ${{steps.branch_name.outputs.BRANCH_NAME}} -f - name: Check if PR exists - if: ${{ steps.fetch_icons.outputs.files_changed == 'true'}} + if: ${{ steps.fetch_icons.outputs.files_changed != ''}} run: echo "pr_exists=$(gh pr list -H ${{steps.branch_name.outputs.BRANCH_NAME}} --json number -q length)" >> $GITHUB_ENV env: GITHUB_TOKEN: ${{ github.token }} - name: Create Pull Request - if: ${{env.pr_exists == 0 && steps.fetch_icons.outputs.files_changed == 'true'}} - run: gh pr create -B main -H ${{steps.branch_name.outputs.BRANCH_NAME}} --title "${{steps.title.outputs.TITLE}}" --body 'Created by the Zeta Icons bot' + if: ${{env.pr_exists == 0 && steps.fetch_icons.outputs.files_changed != ''}} + run: gh pr create -B main -H ${{steps.branch_name.outputs.BRANCH_NAME}} --title "${{steps.title.outputs.TITLE}}" --body '${{steps.title.outputs.BODY}}
Created by the Zeta Icons bot 🤖' env: GITHUB_TOKEN: ${{ github.token }} diff --git a/package-lock.json b/package-lock.json index 188f4d86..9d2db7f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@types/chai": "^4.3.16", "@types/md5": "^2.3.5", "@types/mocha": "^10.0.6", - "@types/node": "^20.12.7", + "@types/node": "^20.17.6", "@types/react": "^18.3.11", "@types/sinon": "^17.0.3", "chai": "^5.1.0", @@ -3200,12 +3200,13 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.12.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", - "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", + "version": "20.17.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.6.tgz", + "integrity": "sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==", "dev": true, + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.2" } }, "node_modules/@types/normalize-package-data": { @@ -10746,10 +10747,11 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" }, "node_modules/unicode-trie": { "version": "2.0.0", diff --git a/package.json b/package.json index 314d70e3..0bcc00af 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "@types/chai": "^4.3.16", "@types/md5": "^2.3.5", "@types/mocha": "^10.0.6", - "@types/node": "^20.12.7", + "@types/node": "^20.17.6", "@types/react": "^18.3.11", "@types/sinon": "^17.0.3", "chai": "^5.1.0", @@ -75,4 +75,4 @@ "url": "https://github.com/zebratechnologies/zeta-icons/issues" }, "homepage": "https://github.com/zebratechnologies/zeta-icons#readme" -} \ No newline at end of file +} diff --git a/scripts/utils/checkGit.ts b/scripts/utils/checkGit.ts index a3f0f6e6..ec3242d6 100644 --- a/scripts/utils/checkGit.ts +++ b/scripts/utils/checkGit.ts @@ -1,16 +1,36 @@ import { execSync } from "child_process"; +// type GitChangeType = "A" | "C" | "D" | "M" | "R" | "T" | "U" | "X" | "B"; +enum GitChangeType { + A = "Added", + C = "Copied", + D = "Deleted", + M = "Modified", + R = "Renamed", + T = "File type changed", + U = "Unmerged", + X = "Unknown", + B = "Broken" +} +export type ChangedFilesDetails = { type: GitChangeType, path: string }; +export const gitChangeTypeToString = (changeType: keyof typeof GitChangeType): string => { + return GitChangeType[changeType]; +}; /** * Gets all files that have changed in the current branch * @param {boolean} verboseLogs - Logs more verbose outputs for testing. - * @returns string[] - List of files that have changed + * @returns { type: GitChangeType, path: string }[] - List of files that have changed with their change type. */ -const getAllChangedFiles = (verboseLogs?: boolean): string[] => { - const diffOutput = execSync(`git diff HEAD --name-only`).toString(); +export const getAllChangedFiles = (verboseLogs?: boolean): ChangedFilesDetails[] => { + const diffOutput = execSync(`git diff HEAD --name-status`).toString(); if (diffOutput != "" && verboseLogs) { console.log("Files changed:", execSync(`git diff HEAD`).toString()); } - return diffOutput.toString().split("\n").filter(Boolean); + return diffOutput.toString().split("\n").map((line) => { + const matches = /^(A|C|D|M|R|T|U|X|B)\s+(.*)$/.exec(line); + if (!matches) return null; + return { type: matches[1] as GitChangeType, path: matches[2] }; + }).filter((change) => change !== null); }; /** @@ -29,9 +49,9 @@ export const stageAllFiles = (verboseLogs?: boolean): void => { * Checks if any files have changed in the current branch. * The check is deliberately off by one to account for `outputs/code-connect.figma.ts` which is not yet regenerated, so will always be changed. * @param {boolean} verboseLogs - Logs more verbose outputs for testing. - * @returns boolean - Whether files have changed and the action should create a PR + * @returns string[] - The list of changed file paths. If files have changed the action should create a PR. */ -export const checkForFileChanges = (verboseLogs?: boolean): boolean => { +export const checkForFileChanges = (verboseLogs?: boolean): ChangedFilesDetails[] => { stageAllFiles(verboseLogs); - return getAllChangedFiles(verboseLogs).length > 1; + return getAllChangedFiles(verboseLogs).filter(({ path }) => path !== "outputs/code-connect.figma.ts"); };