diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0f6a982a..c07f3e35 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -121,3 +121,30 @@ jobs: echo 'steps.files-filtered.outputs.added_modified=${{ steps.files-filtered.outputs.added_modified }}' echo 'steps.files-filtered.outputs.added_modified_renamed=${{ steps.files-filtered.outputs.added_modified_renamed }}' + - id: files-written + name: Run the action and save to a file + uses: ./ + with: + format: 'space-delimited' + output-dir: 'out' + + - name: Check files written + run: | + if ! [ -d out ]; then + echo 'Directory not created' + exit 1 + fi + ls out + + if ! [ -f out/all.txt ]; then + echo 'Output file not created' + exit 1 + fi + + content=$(cat out/all.txt) + echo $content + + if [ "$content" != '${{ steps.files-written.outputs.all }}' ]; then + echo 'Written content does not match expected' + exit 1 + fi diff --git a/README.md b/README.md index f06495b5..18b98491 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ This project is a fork of [jitterbit/get-changed-files](https://github.com/jitte - Considers renamed modified files as modified - Adds `added_modified_renamed` that includes renamed non-modified files and all files in `added_modified` - Removes node12 deprecation warnings +- Supports writing output to file --- @@ -27,6 +28,7 @@ This project is a fork of [jitterbit/get-changed-files](https://github.com/jitte - [Get all changed `*.yml` files but exclude `.github/*/*.yml` files](#get-all-changed-yml-files-but-exclude-githubyml-files) - [Get all added and modified files as CSV](#get-all-added-and-modified-files-as-csv) - [Get all removed files as JSON](#get-all-removed-files-as-json) + - [Write output to files](#write-output-to-files) - [Install, Build, Lint, Test, and Package](#install-build-lint-test-and-package) - [License](#license) @@ -43,6 +45,8 @@ See [action.yml](action.yml) format: '' # Filter files using a glob filter filter: '*' + # Write the output to files in the specified folder + output-dir: 'path/to/folder' ``` ### Filtering @@ -128,6 +132,28 @@ If those two globs were inverted, you **would** include all the YML files, with done ``` +### Write output to files +You can specify the `output-dir` to have the action write the changed files to the specified directory. +Each of the normal outputs (all, renamed, removed, etc) will be written to a file with +the same name as the output and the extension specified by `format` (space-delimited will use .txt). + +For example: + +```yaml +- id: files + uses: Ana06/get-changed-files@v2.3.0 + with: + format: 'json' + output-dir: 'outputs' +``` + +Will write the following files: +- outputs/all.json +- outputs/renamed.json +- outputs/removed.json +- ... + + ## Install, Build, Lint, Test, and Package Make sure to do the following before checking in any code changes. diff --git a/action.yml b/action.yml index babb3fa1..4682d615 100644 --- a/action.yml +++ b/action.yml @@ -21,8 +21,13 @@ inputs: required: true default: space-delimited filter: + description: Filter files to include in the changes using a glob filter. required: true default: '*' + output-dir: + description: Write the changes to files in the specified directory. + required: false + default: '' outputs: all: description: > diff --git a/dist/index.js b/dist/index.js index 3a52783c..a1400dc2 100644 --- a/dist/index.js +++ b/dist/index.js @@ -29,14 +29,17 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); const core = __importStar(__nccwpck_require__(2186)); const github_1 = __nccwpck_require__(5438); const minimatch_1 = __importDefault(__nccwpck_require__(3973)); +const fs = __importStar(__nccwpck_require__(3292)); +const path = __importStar(__nccwpck_require__(1017)); function run() { - var _a, _b, _c, _d; + var _a, _b, _c, _d, _e; return __awaiter(this, void 0, void 0, function* () { try { // Create GitHub client with the API token. const client = new github_1.GitHub(core.getInput('token', { required: true })); const format = core.getInput('format', { required: true }); const filter = core.getMultilineInput('filter', { required: true }) || '*'; + const writeFilesDir = core.getInput('output-dir', { required: false }); // Ensure that the format parameter is set properly. if (format !== 'space-delimited' && format !== 'csv' && format !== 'json') { core.setFailed(`Format must be one of 'string-delimited', 'csv', or 'json', got '${format}'.`); @@ -184,13 +187,34 @@ function run() { core.info(`Added or modified: ${addedModifiedFormatted}`); core.info(`Added, modified or renamed: ${addedModifiedRenamedFormatted}`); // Set step output context. - core.setOutput('all', allFormatted); - core.setOutput('added', addedFormatted); - core.setOutput('modified', modifiedFormatted); - core.setOutput('removed', removedFormatted); - core.setOutput('renamed', renamedFormatted); - core.setOutput('added_modified', addedModifiedFormatted); - core.setOutput('added_modified_renamed', addedModifiedRenamedFormatted); + const outputs = [ + ['all', allFormatted], + ['added', addedFormatted], + ['modified', modifiedFormatted], + ['removed', removedFormatted], + ['renamed', renamedFormatted], + ['added_modified', addedModifiedFormatted], + ['added_modified_renamed', addedModifiedRenamedFormatted] + ]; + for (const [name, content] of outputs) { + core.setOutput(name, content); + } + // Write to file + if (writeFilesDir !== '') { + // Create the folder if it doesn't exist + const dir = path.join((_e = process.env.GITHUB_WORKSPACE) !== null && _e !== void 0 ? _e : '', writeFilesDir); + yield fs.access(dir).catch(() => __awaiter(this, void 0, void 0, function* () { + yield fs.mkdir(dir, { recursive: true }); + })); + const ext = format === 'space-delimited' ? 'txt' : format; + const writes = []; + for (const [name, content] of outputs) { + const file = path.join(dir, `${name}.${ext}`); + writes.push(fs.writeFile(file, content, { flag: 'w+', encoding: 'utf-8' })); + } + yield Promise.all(writes); + core.info(`Output written to ${dir}`); + } // For backwards-compatibility core.setOutput('deleted', removedFormatted); } @@ -28797,6 +28821,14 @@ module.exports = require("fs"); /***/ }), +/***/ 3292: +/***/ ((module) => { + +"use strict"; +module.exports = require("fs/promises"); + +/***/ }), + /***/ 3685: /***/ ((module) => { diff --git a/src/main.ts b/src/main.ts index 1e091610..3f42ae4f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,8 @@ import * as core from '@actions/core' import {context, GitHub} from '@actions/github' import minimatch from 'minimatch' +import * as fs from 'fs/promises' +import * as path from 'path' type Format = 'space-delimited' | 'csv' | 'json' type FileStatus = 'added' | 'modified' | 'removed' | 'renamed' @@ -11,6 +13,7 @@ async function run(): Promise { const client = new GitHub(core.getInput('token', {required: true})) const format = core.getInput('format', {required: true}) as Format const filter = core.getMultilineInput('filter', {required: true}) || '*' + const writeFilesDir = core.getInput('output-dir', {required: false}) // Ensure that the format parameter is set properly. if (format !== 'space-delimited' && format !== 'csv' && format !== 'json') { @@ -196,13 +199,37 @@ async function run(): Promise { core.info(`Added, modified or renamed: ${addedModifiedRenamedFormatted}`) // Set step output context. - core.setOutput('all', allFormatted) - core.setOutput('added', addedFormatted) - core.setOutput('modified', modifiedFormatted) - core.setOutput('removed', removedFormatted) - core.setOutput('renamed', renamedFormatted) - core.setOutput('added_modified', addedModifiedFormatted) - core.setOutput('added_modified_renamed', addedModifiedRenamedFormatted) + const outputs = [ + ['all', allFormatted], + ['added', addedFormatted], + ['modified', modifiedFormatted], + ['removed', removedFormatted], + ['renamed', renamedFormatted], + ['added_modified', addedModifiedFormatted], + ['added_modified_renamed', addedModifiedRenamedFormatted] + ] + + for (const [name, content] of outputs) { + core.setOutput(name, content) + } + + // Write to file + if (writeFilesDir !== '') { + // Create the folder if it doesn't exist + const dir = path.join(process.env.GITHUB_WORKSPACE ?? '', writeFilesDir) + await fs.access(dir).catch(async () => { + await fs.mkdir(dir, {recursive: true}) + }) + + const ext = format === 'space-delimited' ? 'txt' : format + const writes = [] + for (const [name, content] of outputs) { + const file = path.join(dir, `${name}.${ext}`) + writes.push(fs.writeFile(file, content, {flag: 'w+', encoding: 'utf-8'})) + } + await Promise.all(writes) + core.info(`Output written to ${dir}`) + } // For backwards-compatibility core.setOutput('deleted', removedFormatted)