diff --git a/actions/dependency-graph-generate/action.yml b/actions/dependency-graph-generate/action.yml new file mode 100644 index 0000000..3e24b28 --- /dev/null +++ b/actions/dependency-graph-generate/action.yml @@ -0,0 +1,19 @@ +name: "Dependency Graph Generate" +description: Calculates the complete dependency graph for the repository, saving it as a JSON artifact. + +inputs: + gradle-version: + description: Gradle version to use. If specified, this Gradle version will be downloaded, added to the PATH and used for invoking Gradle. + required: false + + gradle-executable: + description: Path to the Gradle executable. If specified, this executable will be added to the PATH and used for invoking Gradle. + required: false + + build-root-directory: + description: Path to the root directory of the build. Default is the root of the GitHub workspace. + required: false + +runs: + using: 'node16' + main: '../../dist/dependency-graph-generate/index.js' diff --git a/actions/dependency-graph-submit/action.yml b/actions/dependency-graph-submit/action.yml new file mode 100644 index 0000000..4f84887 --- /dev/null +++ b/actions/dependency-graph-submit/action.yml @@ -0,0 +1,12 @@ +name: "Dependency Graph Submit" +description: Retrieves a previously created dependency graph JSON and submits via the GitHub Dependency Submission API. + +inputs: + github-token: + description: The GitHub token used to authenticate when submitting via the Dependency Submission API. + default: ${{ github.token }} + required: false + +runs: + using: 'node16' + main: '../../dist/dependency-graph-submit/index.js' diff --git a/package-lock.json b/package-lock.json index 77c774e..00a085f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { + "@actions/artifact": "1.1.1", "@actions/cache": "3.2.1", "@actions/core": "1.10.0", "@actions/exec": "1.1.1", @@ -17,6 +18,7 @@ "@actions/glob": "0.4.0", "@actions/http-client": "2.1.0", "@actions/tool-cache": "2.0.1", + "@octokit/rest": "19.0.11", "string-argv": "0.3.2" }, "devDependencies": { @@ -36,6 +38,28 @@ "typescript": "5.0.4" } }, + "node_modules/@actions/artifact": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-1.1.1.tgz", + "integrity": "sha512-Vv4y0EW0ptEkU+Pjs5RGS/0EryTvI6s79LjSV9Gg/h+O3H/ddpjhuX/Bi/HZE4pbNPyjGtQjbdFWphkZhmgabA==", + "dependencies": { + "@actions/core": "^1.9.1", + "@actions/http-client": "^2.0.1", + "tmp": "^0.2.1", + "tmp-promise": "^3.0.2" + } + }, + "node_modules/@actions/artifact/node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, "node_modules/@actions/cache": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-3.2.1.tgz", @@ -1535,6 +1559,14 @@ "@octokit/core": ">=2" } }, + "node_modules/@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "peerDependencies": { + "@octokit/core": ">=3" + } + }, "node_modules/@octokit/plugin-rest-endpoint-methods": { "version": "5.16.2", "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz", @@ -1570,6 +1602,151 @@ "once": "^1.4.0" } }, + "node_modules/@octokit/rest": { + "version": "19.0.11", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.11.tgz", + "integrity": "sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw==", + "dependencies": { + "@octokit/core": "^4.2.1", + "@octokit/plugin-paginate-rest": "^6.1.2", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^7.1.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/rest/node_modules/@octokit/auth-token": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.3.tgz", + "integrity": "sha512-/aFM2M4HVDBT/jjDBa84sJniv1t9Gm/rLkalaz9htOm+L+8JMj1k9w0CkUdcxNyNxZPlTxKPVko+m1VlM58ZVA==", + "dependencies": { + "@octokit/types": "^9.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/rest/node_modules/@octokit/core": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.1.tgz", + "integrity": "sha512-tEDxFx8E38zF3gT7sSMDrT1tGumDgsw5yPG6BBh/X+5ClIQfMH/Yqocxz1PnHx6CHyF6pxmovUTOfZAUvQ0Lvw==", + "dependencies": { + "@octokit/auth-token": "^3.0.0", + "@octokit/graphql": "^5.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/rest/node_modules/@octokit/endpoint": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.5.tgz", + "integrity": "sha512-LG4o4HMY1Xoaec87IqQ41TQ+glvIeTKqfjkCEmt5AIwDZJwQeVZFIEYXrYY6yLwK+pAScb9Gj4q+Nz2qSw1roA==", + "dependencies": { + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/rest/node_modules/@octokit/graphql": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", + "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", + "dependencies": { + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/rest/node_modules/@octokit/openapi-types": { + "version": "17.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-17.2.0.tgz", + "integrity": "sha512-MazrFNx4plbLsGl+LFesMo96eIXkFgEtaKbnNpdh4aQ0VM10aoylFsTYP1AEjkeoRNZiiPe3T6Gl2Hr8dJWdlQ==" + }, + "node_modules/@octokit/rest/node_modules/@octokit/plugin-paginate-rest": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz", + "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==", + "dependencies": { + "@octokit/tsconfig": "^1.0.2", + "@octokit/types": "^9.2.3" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "@octokit/core": ">=4" + } + }, + "node_modules/@octokit/rest/node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.1.2.tgz", + "integrity": "sha512-R0oJ7j6f/AdqPLtB9qRXLO+wjI9pctUn8Ka8UGfGaFCcCv3Otx14CshQ89K4E88pmyYZS8p0rNTiprML/81jig==", + "dependencies": { + "@octokit/types": "^9.2.3", + "deprecation": "^2.3.1" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/rest/node_modules/@octokit/request": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.5.tgz", + "integrity": "sha512-z83E8UIlPNaJUsXpjD8E0V5o/5f+vJJNbNcBwVZsX3/vC650U41cOkTLjq4PKk9BYonQGOnx7N17gvLyNjgGcQ==", + "dependencies": { + "@octokit/endpoint": "^7.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/rest/node_modules/@octokit/request-error": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz", + "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", + "dependencies": { + "@octokit/types": "^9.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/rest/node_modules/@octokit/types": { + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.2.3.tgz", + "integrity": "sha512-MMeLdHyFIALioycq+LFcA71v0S2xpQUX2cw6pPbHQjaibcHYwLnmK/kMZaWuGfGfjBJZ3wRUq+dOaWsvrPJVvA==", + "dependencies": { + "@octokit/openapi-types": "^17.2.0" + } + }, + "node_modules/@octokit/tsconfig": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz", + "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==" + }, "node_modules/@octokit/types": { "version": "6.41.0", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", @@ -3833,8 +4010,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.2", @@ -3956,7 +4132,6 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4211,7 +4386,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -4220,8 +4394,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/internal-slot": { "version": "1.0.4", @@ -5965,7 +6138,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -6337,7 +6509,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -6689,6 +6860,25 @@ "node": ">=0.6.0" } }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dependencies": { + "tmp": "^0.2.0" + } + }, + "node_modules/tmp-promise/node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -7248,6 +7438,27 @@ } }, "dependencies": { + "@actions/artifact": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-1.1.1.tgz", + "integrity": "sha512-Vv4y0EW0ptEkU+Pjs5RGS/0EryTvI6s79LjSV9Gg/h+O3H/ddpjhuX/Bi/HZE4pbNPyjGtQjbdFWphkZhmgabA==", + "requires": { + "@actions/core": "^1.9.1", + "@actions/http-client": "^2.0.1", + "tmp": "^0.2.1", + "tmp-promise": "^3.0.2" + }, + "dependencies": { + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "requires": { + "rimraf": "^3.0.0" + } + } + } + }, "@actions/cache": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-3.2.1.tgz", @@ -8438,6 +8649,12 @@ "@octokit/types": "^6.40.0" } }, + "@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "requires": {} + }, "@octokit/plugin-rest-endpoint-methods": { "version": "5.16.2", "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz", @@ -8470,6 +8687,120 @@ "once": "^1.4.0" } }, + "@octokit/rest": { + "version": "19.0.11", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.11.tgz", + "integrity": "sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw==", + "requires": { + "@octokit/core": "^4.2.1", + "@octokit/plugin-paginate-rest": "^6.1.2", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^7.1.2" + }, + "dependencies": { + "@octokit/auth-token": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.3.tgz", + "integrity": "sha512-/aFM2M4HVDBT/jjDBa84sJniv1t9Gm/rLkalaz9htOm+L+8JMj1k9w0CkUdcxNyNxZPlTxKPVko+m1VlM58ZVA==", + "requires": { + "@octokit/types": "^9.0.0" + } + }, + "@octokit/core": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.1.tgz", + "integrity": "sha512-tEDxFx8E38zF3gT7sSMDrT1tGumDgsw5yPG6BBh/X+5ClIQfMH/Yqocxz1PnHx6CHyF6pxmovUTOfZAUvQ0Lvw==", + "requires": { + "@octokit/auth-token": "^3.0.0", + "@octokit/graphql": "^5.0.0", + "@octokit/request": "^6.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/endpoint": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.5.tgz", + "integrity": "sha512-LG4o4HMY1Xoaec87IqQ41TQ+glvIeTKqfjkCEmt5AIwDZJwQeVZFIEYXrYY6yLwK+pAScb9Gj4q+Nz2qSw1roA==", + "requires": { + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/graphql": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", + "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", + "requires": { + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/openapi-types": { + "version": "17.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-17.2.0.tgz", + "integrity": "sha512-MazrFNx4plbLsGl+LFesMo96eIXkFgEtaKbnNpdh4aQ0VM10aoylFsTYP1AEjkeoRNZiiPe3T6Gl2Hr8dJWdlQ==" + }, + "@octokit/plugin-paginate-rest": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz", + "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==", + "requires": { + "@octokit/tsconfig": "^1.0.2", + "@octokit/types": "^9.2.3" + } + }, + "@octokit/plugin-rest-endpoint-methods": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.1.2.tgz", + "integrity": "sha512-R0oJ7j6f/AdqPLtB9qRXLO+wjI9pctUn8Ka8UGfGaFCcCv3Otx14CshQ89K4E88pmyYZS8p0rNTiprML/81jig==", + "requires": { + "@octokit/types": "^9.2.3", + "deprecation": "^2.3.1" + } + }, + "@octokit/request": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.5.tgz", + "integrity": "sha512-z83E8UIlPNaJUsXpjD8E0V5o/5f+vJJNbNcBwVZsX3/vC650U41cOkTLjq4PKk9BYonQGOnx7N17gvLyNjgGcQ==", + "requires": { + "@octokit/endpoint": "^7.0.0", + "@octokit/request-error": "^3.0.0", + "@octokit/types": "^9.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz", + "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", + "requires": { + "@octokit/types": "^9.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/types": { + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.2.3.tgz", + "integrity": "sha512-MMeLdHyFIALioycq+LFcA71v0S2xpQUX2cw6pPbHQjaibcHYwLnmK/kMZaWuGfGfjBJZ3wRUq+dOaWsvrPJVvA==", + "requires": { + "@octokit/openapi-types": "^17.2.0" + } + } + } + }, + "@octokit/tsconfig": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz", + "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==" + }, "@octokit/types": { "version": "6.41.0", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", @@ -10158,8 +10489,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.3.2", @@ -10241,7 +10571,6 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -10412,7 +10741,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -10421,8 +10749,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "internal-slot": { "version": "1.0.4", @@ -11711,8 +12038,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { "version": "3.1.1", @@ -11960,7 +12286,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -12217,6 +12542,24 @@ "os-tmpdir": "~1.0.2" } }, + "tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "requires": { + "tmp": "^0.2.0" + }, + "dependencies": { + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "requires": { + "rimraf": "^3.0.0" + } + } + } + }, "tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", diff --git a/package.json b/package.json index 8074efb..18b99c0 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,13 @@ "format": "prettier --write **/*.ts", "format-check": "prettier --check **/*.ts", "lint": "eslint src/**/*.ts", - "compile": "ncc build src/main.ts --out dist/main --source-map --no-source-map-register && ncc build src/post.ts --out dist/post --source-map --no-source-map-register", + + "compile-main": "ncc build src/main.ts --out dist/main --source-map --no-source-map-register", + "compile-post": "ncc build src/post.ts --out dist/post --source-map --no-source-map-register", + "compile-dependency-graph-generate": "ncc build src/dependency-graph-generate.ts --out dist/dependency-graph-generate --source-map --no-source-map-register", + "compile-dependency-graph-submit": "ncc build src/dependency-graph-submit.ts --out dist/dependency-graph-submit --source-map --no-source-map-register", + "compile": "npm run compile-main && npm run compile-post && npm run compile-dependency-graph-generate && npm run compile-dependency-graph-submit", + "test": "jest", "check": "npm run format && npm run lint", "build": "npm run check && npm run compile", @@ -26,6 +32,7 @@ ], "license": "MIT", "dependencies": { + "@actions/artifact": "1.1.1", "@actions/cache": "3.2.1", "@actions/core": "1.10.0", "@actions/exec": "1.1.1", @@ -33,6 +40,7 @@ "@actions/glob": "0.4.0", "@actions/http-client": "2.1.0", "@actions/tool-cache": "2.0.1", + "@octokit/rest": "19.0.11", "string-argv": "0.3.2" }, "devDependencies": { diff --git a/src/dependency-graph-generate.ts b/src/dependency-graph-generate.ts new file mode 100644 index 0000000..571e91c --- /dev/null +++ b/src/dependency-graph-generate.ts @@ -0,0 +1,24 @@ +import * as core from '@actions/core' + +import * as provisioner from './provision' +import * as dependencyGraph from './dependency-graph' + +/** + * The main entry point for the action, called by Github Actions for the step. + */ +export async function run(): Promise { + try { + // Download and install Gradle if required + const executable = await provisioner.provisionGradle() + + // Generate and upload dependency graph artifact + await dependencyGraph.generateDependencyGraph(executable) + } catch (error) { + core.setFailed(String(error)) + if (error instanceof Error && error.stack) { + core.info(error.stack) + } + } +} + +run() diff --git a/src/dependency-graph-submit.ts b/src/dependency-graph-submit.ts new file mode 100644 index 0000000..f0be2e6 --- /dev/null +++ b/src/dependency-graph-submit.ts @@ -0,0 +1,16 @@ +import * as core from '@actions/core' +import * as dependencyGraph from './dependency-graph' + +export async function run(): Promise { + try { + // Retrieve the dependency graph artifact and submit via Dependency Submission API + await dependencyGraph.submitDependencyGraph() + } catch (error) { + core.setFailed(String(error)) + if (error instanceof Error && error.stack) { + core.info(error.stack) + } + } +} + +run() diff --git a/src/dependency-graph.ts b/src/dependency-graph.ts new file mode 100644 index 0000000..31f5390 --- /dev/null +++ b/src/dependency-graph.ts @@ -0,0 +1,155 @@ +import * as core from '@actions/core' +import * as artifact from '@actions/artifact' +import * as github from '@actions/github' +import * as glob from '@actions/glob' +import * as toolCache from '@actions/tool-cache' +import {Octokit} from '@octokit/rest' + +import * as path from 'path' +import fs from 'fs' + +import * as execution from './execution' +import * as layout from './repository-layout' + +const DEPENDENCY_GRAPH_ARTIFACT = 'dependency-graph' +const DEPENDENCY_GRAPH_FILE = 'dependency-graph.json' + +export async function generateDependencyGraph(executable: string | undefined): Promise { + const workspaceDirectory = layout.workspaceDirectory() + const buildRootDirectory = layout.buildRootDirectory() + const buildPath = getRelativePathFromWorkspace(buildRootDirectory) + + const initScript = path.resolve( + __dirname, + '..', + '..', + 'src', + 'resources', + 'init-scripts', + 'github-dependency-graph.init.gradle' + ) + const args = [ + `-Dorg.gradle.github.env.GRADLE_BUILD_PATH=${buildPath}`, + '--init-script', + initScript, + ':GitHubDependencyGraphPlugin_generateDependencyGraph' + ] + + await execution.executeGradleBuild(executable, buildRootDirectory, args) + const dependencyGraphJson = copyDependencyGraphToBuildRoot(buildRootDirectory) + + const artifactClient = artifact.create() + artifactClient.uploadArtifact(DEPENDENCY_GRAPH_ARTIFACT, [dependencyGraphJson], workspaceDirectory) +} + +function copyDependencyGraphToBuildRoot(buildRootDirectory: string): string { + const sourceFile = path.resolve( + buildRootDirectory, + 'build', + 'reports', + 'github-dependency-graph-plugin', + 'github-dependency-snapshot.json' + ) + + const destFile = path.resolve(buildRootDirectory, DEPENDENCY_GRAPH_FILE) + fs.copyFileSync(sourceFile, destFile) + return destFile +} + +export async function submitDependencyGraph(): Promise { + const workspaceDirectory = layout.workspaceDirectory() + const octokit: Octokit = getOctokit() + + for (const jsonFile of await retrieveDependencyGraphs(octokit, workspaceDirectory)) { + const jsonContent = fs.readFileSync(jsonFile, 'utf8') + + const jsonObject = JSON.parse(jsonContent) + jsonObject.owner = github.context.repo.owner + jsonObject.repo = github.context.repo.repo + const response = await octokit.request('POST /repos/{owner}/{repo}/dependency-graph/snapshots', jsonObject) + + const relativeJsonFile = getRelativePathFromWorkspace(jsonFile) + core.info(`Submitted ${relativeJsonFile}: ${JSON.stringify(response)}`) + core.notice(`Submitted ${relativeJsonFile}: ${response.data.message}`) + } +} + +async function findDependencyGraphFiles(dir: string): Promise { + const globber = await glob.create(`${dir}/**/${DEPENDENCY_GRAPH_FILE}`) + const graphFiles = globber.glob() + core.info(`Found graph files in ${dir}: ${graphFiles}`) + return graphFiles +} + +async function retrieveDependencyGraphs(octokit: Octokit, workspaceDirectory: string): Promise { + if (github.context.payload.workflow_run) { + return await retrieveDependencyGraphsForWorkflowRun( + github.context.payload.workflow_run.id, + octokit, + workspaceDirectory + ) + } + return retrieveDependencyGraphsForCurrentWorkflow(workspaceDirectory) +} + +async function retrieveDependencyGraphsForWorkflowRun( + runId: number, + octokit: Octokit, + workspaceDirectory: string +): Promise { + // Find the workflow run artifacts named "dependency-graph" + const artifacts = await octokit.rest.actions.listWorkflowRunArtifacts({ + owner: github.context.repo.owner, + repo: github.context.repo.repo, + run_id: runId + }) + + const matchArtifact = artifacts.data.artifacts.find(candidate => { + return candidate.name === DEPENDENCY_GRAPH_ARTIFACT + }) + + if (matchArtifact === undefined) { + throw new Error(`Dependency graph artifact not found. Has it been generated by workflow run '${runId}'?`) + } + + // Download the dependency-graph artifact + const download = await octokit.rest.actions.downloadArtifact({ + owner: github.context.repo.owner, + repo: github.context.repo.repo, + artifact_id: matchArtifact.id, + archive_format: 'zip' + }) + + const downloadBuffer = download.data as ArrayBuffer + const downloadZip = path.resolve(workspaceDirectory, 'dependency-graph.zip') + fs.writeFileSync(downloadZip, Buffer.from(downloadBuffer)) + + // Expance the dependency-graph zip and locate each dependency-graph JSON file + const extractDir = path.resolve(workspaceDirectory, 'dependency-graph') + const extracted = await toolCache.extractZip(downloadZip, extractDir) + core.info(`Extracted dependency graph artifacts to ${extracted}: ${fs.readdirSync(extracted)}`) + + return findDependencyGraphFiles(extracted) +} + +async function retrieveDependencyGraphsForCurrentWorkflow(workspaceDirectory: string): Promise { + const artifactClient = artifact.create() + const downloadPath = path.resolve(workspaceDirectory, 'dependency-graph') + await artifactClient.downloadArtifact(DEPENDENCY_GRAPH_ARTIFACT, downloadPath) + return await findDependencyGraphFiles(downloadPath) +} + +function getOctokit(): Octokit { + return new Octokit({ + auth: getGithubToken() + }) +} + +function getGithubToken(): string { + return core.getInput('github-token', {required: true}) +} + +function getRelativePathFromWorkspace(file: string): string { + const workspaceDirectory = layout.workspaceDirectory() + return path.relative(workspaceDirectory, file) +} diff --git a/src/resources/init-scripts/github-dependency-graph.init.gradle b/src/resources/init-scripts/github-dependency-graph.init.gradle new file mode 100644 index 0000000..edb2696 --- /dev/null +++ b/src/resources/init-scripts/github-dependency-graph.init.gradle @@ -0,0 +1,12 @@ +import org.gradle.github.GitHubDependencyGraphPlugin +initscript { + repositories { + maven { + url = uri("https://plugins.gradle.org/m2/") + } + } + dependencies { + classpath("org.gradle:github-dependency-graph-gradle-plugin:+") + } +} +apply plugin: GitHubDependencyGraphPlugin