diff --git a/README.md b/README.md index 7f46d67..15206c9 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ jobs: name: build, pack & publish runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v2.5.9 # - name: Setup dotnet # uses: actions/setup-dotnet@v1 @@ -48,7 +48,7 @@ jobs: # Format of the git tag, [*] gets replaced with actual version # TAG_FORMAT: v* - # API key to authenticate with NuGet server + # API key to authenticate with NuGet server, or a token, issued for GITHUB_USER if you use GPR # NUGET_KEY: ${{secrets.NUGET_API_KEY}} # NuGet server uri hosting the packages, defaults to https://api.nuget.org @@ -56,6 +56,9 @@ jobs: # Flag to toggle pushing symbols along with nuget package to the server, disabled by default # INCLUDE_SYMBOLS: false + + # Flag to throw an error when trying to publish an existing version of a package + # THOW_ERROR_IF_VERSION_EXISTS: false ``` - Project gets published only if there's a `NUGET_KEY` configured in the repository @@ -71,9 +74,11 @@ VERSION_REGEX | `^\s*(.*)<\/Version>\s*$` | Regex pattern to extract ve VERSION_STATIC| | Useful with external providers like Nerdbank.GitVersioning, ignores VERSION_FILE_PATH & VERSION_REGEX TAG_COMMIT | `true` | Flag to toggle git tagging, enabled by default TAG_FORMAT | `v*` | Format of the git tag, `[*]` gets replaced with actual version -NUGET_KEY | | API key to authenticate with NuGet server +GITHUB_USER |`[GITHUB_ACTOR]` | Required for packages pushed to Github Package Registry. User allowed to push to repository, defaults to GITHUB_ACTOR (user that triggered the action) +NUGET_KEY | | API key to authenticate with NuGet server, or a token, issued for GITHUB_USER if you use GPR NUGET_SOURCE | `https://api.nuget.org` | NuGet server uri hosting the packages, defaults to https://api.nuget.org INCLUDE_SYMBOLS | `false` | Flag to toggle pushing symbols along with nuget package to the server, disabled by default +THOW_ERROR_IF_VERSION_EXISTS | `false` | Flag to throw an error when trying to publish an existing version of a package ## Outputs @@ -87,7 +92,7 @@ SYMBOLS_PACKAGE_PATH | Path to the generated symbols package **FYI:** - Outputs may or may not be set depending on the action inputs or if the action failed -- `NUGET_SOURCE` must support `/v3-flatcontainer/PACKAGE_NAME/index.json` for version change detection to work +- ~`NUGET_SOURCE` must support `/v3-flatcontainer/PACKAGE_NAME/index.json` for version change detection to work~ - Multiple projects can make use of steps to configure each project individually, common inputs between steps can be given as `env` for [job / workflow](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#env) ## License diff --git a/action.yml b/action.yml index 9dc71b2..5874713 100644 --- a/action.yml +++ b/action.yml @@ -1,6 +1,6 @@ -name: Publish NuGet -author: Rohith Reddy (@rohith) -description: Build, Pack & Publish a NuGet package with dotnet core on project version change +name: Publish NuGet 2 +author: Rebel028 +description: Temporary fork of https://github.com/brandedoutcast/publish-nuget/ inputs: PROJECT_FILE_PATH: @@ -27,8 +27,11 @@ inputs: description: Format of the git tag, [*] gets replaced with actual version required: false default: v* + GITHUB_USER: + description: Required for packages pushed to Github Package Registry. User allowed to push to repository, defaults to GITHUB_ACTOR (user that triggered the action) + required: false NUGET_KEY: - description: API key to authenticate with NuGet server + description: API key to authenticate with NuGet server, or a token, issued for GITHUB_USER if you use GPR required: false NUGET_SOURCE: description: NuGet server uri hosting the packages, defaults to https://api.nuget.org @@ -38,6 +41,10 @@ inputs: description: Flag to toggle pushing symbols along with nuget package to the server, disabled by default required: false default: false + THOW_ERROR_IF_VERSION_EXISTS: + description: Flag to throw an error when trying to publish an existing version of a package + required: false + default: false outputs: VERSION: @@ -61,4 +68,4 @@ runs: branding: icon: package - color: blue \ No newline at end of file + color: blue diff --git a/index.js b/index.js index db47a6d..1a3967d 100644 --- a/index.js +++ b/index.js @@ -4,7 +4,11 @@ const os = require("os"), https = require("https"), spawnSync = require("child_process").spawnSync +const SOURCE_NAME = "default"; + class Action { + + constructor() { this.projectFile = process.env.INPUT_PROJECT_FILE_PATH this.packageName = process.env.INPUT_PACKAGE_NAME || process.env.PACKAGE_NAME @@ -13,9 +17,26 @@ class Action { this.version = process.env.INPUT_VERSION_STATIC || process.env.VERSION_STATIC this.tagCommit = JSON.parse(process.env.INPUT_TAG_COMMIT || process.env.TAG_COMMIT) this.tagFormat = process.env.INPUT_TAG_FORMAT || process.env.TAG_FORMAT + this.githubUser = process.env.INPUT_GITHUB_USER || process.env.GITHUB_ACTOR this.nugetKey = process.env.INPUT_NUGET_KEY || process.env.NUGET_KEY this.nugetSource = process.env.INPUT_NUGET_SOURCE || process.env.NUGET_SOURCE this.includeSymbols = JSON.parse(process.env.INPUT_INCLUDE_SYMBOLS || process.env.INCLUDE_SYMBOLS) + this.throwOnVersionExixts = process.env.INPUT_THOW_ERROR_IF_VERSION_EXISTS || process.env.THOW_ERROR_IF_VERSION_EXISTS + + let addSourceCmd; + if (this.nugetSource.startsWith(`https://nuget.pkg.github.com/`)) { + this.sourceType = "GPR" + addSourceCmd = `dotnet nuget add source ${this.nugetSource}/index.json --name=${(SOURCE_NAME)} --username=${this.githubUser} --password=${this.nugetKey} --store-password-in-clear-text` + } else { + this.sourceType = "NuGet" + addSourceCmd = `dotnet nuget add source ${this.nugetSource}/v3/index.json --name=${SOURCE_NAME}` + } + + console.log(this._executeCommand(addSourceCmd, { encoding: "utf-8" }).stdout) + const list1 = this._executeCommand("dotnet nuget list source", { encoding: "utf8" }).stdout; + const enable = this._executeCommand(`dotnet nuget enable source ${SOURCE_NAME}`, { encoding: "utf8" }).stdout; + console.log(list1); + console.log(enable); } _printErrorAndExit(msg) { @@ -56,7 +77,7 @@ class Action { console.log(`NuGet Source: ${this.nugetSource}`) fs.readdirSync(".").filter(fn => /\.s?nupkg$/.test(fn)).forEach(fn => fs.unlinkSync(fn)) - + this._executeInProcess(`dotnet build -c Release ${this.projectFile}`) this._executeInProcess(`dotnet pack ${this.includeSymbols ? "--include-symbols -p:SymbolPackageFormat=snupkg" : ""} --no-build -c Release ${this.projectFile} -o .`) @@ -64,8 +85,9 @@ class Action { const packages = fs.readdirSync(".").filter(fn => fn.endsWith("nupkg")) console.log(`Generated Package(s): ${packages.join(", ")}`) - const pushCmd = `dotnet nuget push *.nupkg -s ${this.nugetSource}/v3/index.json -k ${this.nugetKey} --skip-duplicate ${!this.includeSymbols ? "-n 1" : ""}`, - pushOutput = this._executeCommand(pushCmd, { encoding: "utf-8" }).stdout + const pushCmd = `dotnet nuget push *.nupkg -s ${(SOURCE_NAME)} ${this.nugetSource !== "GPR"? `-k ${this.nugetKey}`: ""} --skip-duplicate ${!this.includeSymbols ? "-n 1" : ""}` + + const pushOutput = this._executeCommand(pushCmd, { encoding: "utf-8" }).stdout console.log(pushOutput) @@ -94,21 +116,55 @@ class Action { console.log(`Package Name: ${this.packageName}`) - https.get(`${this.nugetSource}/v3-flatcontainer/${this.packageName}/index.json`, res => { + let url = "" + let options; //used for authentication + + //small hack to get package versions from Github Package Registry + if (this.sourceType === "GPR") { + url = `${this.nugetSource}/download/${this.packageName}/index.json` + options = { + method: "GET", + auth:`${this.githubUser}:${this.nugetKey}` + } + console.log(`This is GPR, changing url for versioning...`) + console.log(url) + } else { + url = `${this.nugetSource}/v3-flatcontainer/${this.packageName}/index.json` + } + + https.get(url, options, (res) => { let body = "" + + console.log(`Status code: ${res.statusCode}: ${res.statusMessage}`) - if (res.statusCode == 404) + if (res.statusCode == 404){ + console.log(`No packages found. Pushing initial version...`) this._pushPackage(this.version, this.packageName) - - if (res.statusCode == 200) { + } + else if (res.statusCode == 200) { res.setEncoding("utf8") res.on("data", chunk => body += chunk) res.on("end", () => { const existingVersions = JSON.parse(body) - if (existingVersions.versions.indexOf(this.version) < 0) + if (existingVersions.versions.indexOf(this.version) < 0) { + console.log(`This version is new, pushing...`) this._pushPackage(this.version, this.packageName) + } + else + { + let errorMsg = `Version ${this.version} already exists`; + console.log(errorMsg) + + if(this.throwOnVersionExixts) { + this._printErrorAndExit(`error: ${errorMsg}`) + } + } }) } + else { + this._printErrorAndExit(`error: ${res.statusCode}: ${res.statusMessage}`) + } + }).on("error", e => { this._printErrorAndExit(`error: ${e.message}`) })