Skip to content

Commit

Permalink
add support for custom NuGet package name
Browse files Browse the repository at this point in the history
* Add ability to specify PACKAGE_NAME (brandedoutcast#12)
* Add package name capabilities
  • Loading branch information
Deadpikle authored and brandedoutcast committed Feb 27, 2020
1 parent 23486ff commit dbb450e
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 122 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ name: publish to nuget
on:
push:
branches:
- master # Your default release branch
- master # Default release branch
jobs:
publish:
name: list on nuget
Expand All @@ -34,6 +34,7 @@ jobs:
# TAG_COMMIT: true # Flag to enable / disalge git tagging
# TAG_FORMAT: v* # Format of the git tag, [*] gets replaced with version
# NUGET_KEY: ${{secrets.NUGET_API_KEY}} # nuget.org API key
# PACKAGE_NAME: NuGet package name, required when it's different from project name. Defaults to project name
```

- With all settings on default, updates to project version are monitored on every push / PR merge to master & a new tag is created
Expand All @@ -50,6 +51,7 @@ VERSION_REGEX | `<Version>(.*)<\/Version>` | Regex pattern to extract version in
TAG_COMMIT | `true` | Flag to enable / disable git tagging
TAG_FORMAT | `v*` | `[*]` is a placeholder for the actual project version
NUGET_KEY | | API key to authorize the package upload to nuget.org
PACKAGE_NAME | | Name of the NuGet package, required when it's different from project name

**Note:**
For multiple projects, every input except `PROJECT_FILE_PATH` can be given as `env` variable at [job / workflow level](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#env)
Expand Down
5 changes: 4 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ inputs:
required: false
default: <Version>(.*)<\/Version>
TAG_COMMIT:
description: Whether to create a tag when there's a version change or not
description: Whether to create a tag when there's a version change
required: false
default: true
TAG_FORMAT:
Expand All @@ -24,6 +24,9 @@ inputs:
NUGET_KEY:
description: API key for the NuGet feed
required: false
PACKAGE_NAME:
description: NuGet package name, required when it's different from the project name
required: false

runs:
using: node12
Expand Down
243 changes: 123 additions & 120 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,120 +1,123 @@
const path = require("path"),
spawnSync = require("child_process").spawnSync,
fs = require("fs"),
https = require("https")

class Action {
constructor() {
this.PROJECT_FILE_PATH = process.env.INPUT_PROJECT_FILE_PATH
this.VERSION_FILE_PATH = process.env.INPUT_VERSION_FILE_PATH || process.env.VERSION_FILE_PATH
this.VERSION_REGEX = new RegExp(process.env.INPUT_VERSION_REGEX || process.env.VERSION_REGEX)
this.TAG_COMMIT = JSON.parse(process.env.INPUT_TAG_COMMIT || process.env.TAG_COMMIT)
this.TAG_FORMAT = process.env.INPUT_TAG_FORMAT || process.env.TAG_FORMAT
this.NUGET_KEY = process.env.INPUT_NUGET_KEY || process.env.NUGET_KEY
}

_warn(msg) {
console.log(`##[warning]${msg}`)
}

_fail(msg) {
console.log(`##[error]${msg}`)
throw new Error(msg)
}

_execCmd(cmd, options) {
const INPUT = cmd.split(" "), TOOL = INPUT[0], ARGS = INPUT.slice(1)
return spawnSync(TOOL, ARGS, options)
}

_execAndCapture(cmd) {
return this._execCmd(cmd, { encoding: "utf-8" }).stdout
}

_execInProc(cmd) {
this._execCmd(cmd, { encoding: "utf-8", stdio: [process.stdin, process.stdout, process.stderr] })
}

_resolveIfExists(filePath, msg) {
const FULLPATH = path.resolve(process.env.GITHUB_WORKSPACE, filePath)
if (!fs.existsSync(FULLPATH)) this._fail(msg)
return FULLPATH
}

_pushPackage() {
if (!this.NUGET_KEY) {
this._warn("😢 nuget_key not given")
return
}

if (!this._execAndCapture("dotnet --version")) {
this._warn("😭 dotnet not found")
return
}

this._execInProc(`dotnet pack -c Release ${this.PROJECT_FILE_PATH} -o .`)
const NUGET_PUSH_RESPONSE = this._execAndCapture(`dotnet nuget push *.nupkg -s https://api.nuget.org/v3/index.json -k ${this.NUGET_KEY}`)
const NUGET_ERROR_REGEX = /(error: Response status code does not indicate success.*)/

if (NUGET_ERROR_REGEX.test(NUGET_PUSH_RESPONSE))
this._fail(`😭 ${NUGET_ERROR_REGEX.exec(NUGET_PUSH_RESPONSE)[1]}`)
}

_tagCommit(version) {
if (this.TAG_COMMIT) {
const TAG = this.TAG_FORMAT.replace("*", version)

if (this._execAndCapture(`git ls-remote --tags origin ${TAG}`).indexOf(TAG) >= 0) {
this._warn(`😢 tag ${TAG} already exists`)
return
}

this._execInProc(`git tag ${TAG}`)
this._execInProc(`git push origin ${TAG}`)
}
}

_pushAndTag(CURRENT_VERSION, PACKAGE_NAME) {
console.log(`👍 found a new version (${CURRENT_VERSION}) of ${PACKAGE_NAME}`)
this._tagCommit(CURRENT_VERSION)
this._pushPackage()
}

run() {
if (!this.PROJECT_FILE_PATH)
this._fail("😭 project file not given")

this.PROJECT_FILE_PATH = this._resolveIfExists(this.PROJECT_FILE_PATH, "😭 project file not found")
this.VERSION_FILE_PATH = !this.VERSION_FILE_PATH ? this.PROJECT_FILE_PATH : this._resolveIfExists(this.VERSION_FILE_PATH, "😭 version file not found")

const FILE_CONTENT = fs.readFileSync(this.VERSION_FILE_PATH, { encoding: "utf-8" }),
VERSION_INFO = this.VERSION_REGEX.exec(FILE_CONTENT)

if (!VERSION_INFO)
this._fail("😢 unable to extract version info")

const CURRENT_VERSION = VERSION_INFO[1],
PACKAGE_NAME = path.basename(this.PROJECT_FILE_PATH).split(".").slice(0, -1).join(".")

https.get(`https://api.nuget.org/v3-flatcontainer/${PACKAGE_NAME}/index.json`, res => {
let body = ""

if (res.statusCode == 404)
this._pushAndTag(CURRENT_VERSION, PACKAGE_NAME)

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(CURRENT_VERSION) < 0)
this._pushAndTag(CURRENT_VERSION, PACKAGE_NAME)
})
}
}).on("error", e => {
this._warn(`😢 error reaching nuget.org ${e.message}`)
})
}
}

new Action().run()
const path = require("path"),
spawnSync = require("child_process").spawnSync,
fs = require("fs"),
https = require("https")

class Action {
constructor() {
this.PROJECT_FILE_PATH = process.env.INPUT_PROJECT_FILE_PATH
this.VERSION_FILE_PATH = process.env.INPUT_VERSION_FILE_PATH || process.env.VERSION_FILE_PATH
this.VERSION_REGEX = new RegExp(process.env.INPUT_VERSION_REGEX || process.env.VERSION_REGEX)
this.TAG_COMMIT = JSON.parse(process.env.INPUT_TAG_COMMIT || process.env.TAG_COMMIT)
this.TAG_FORMAT = process.env.INPUT_TAG_FORMAT || process.env.TAG_FORMAT
this.NUGET_KEY = process.env.INPUT_NUGET_KEY || process.env.NUGET_KEY
this.PACKAGE_NAME = process.env.INPUT_PACKAGE_NAME || process.env.PACKAGE_NAME
}

_warn(msg) {
console.log(`##[warning]${msg}`)
}

_fail(msg) {
console.log(`##[error]${msg}`)
throw new Error(msg)
}

_execCmd(cmd, options) {
const INPUT = cmd.split(" "), TOOL = INPUT[0], ARGS = INPUT.slice(1)
return spawnSync(TOOL, ARGS, options)
}

_execAndCapture(cmd) {
return this._execCmd(cmd, { encoding: "utf-8" }).stdout
}

_execInProc(cmd) {
this._execCmd(cmd, { encoding: "utf-8", stdio: [process.stdin, process.stdout, process.stderr] })
}

_resolveIfExists(filePath, msg) {
const FULLPATH = path.resolve(process.env.GITHUB_WORKSPACE, filePath)
if (!fs.existsSync(FULLPATH)) this._fail(msg)
return FULLPATH
}

_pushPackage() {
if (!this.NUGET_KEY) {
this._warn("😢 nuget_key not given")
return
}

if (!this._execAndCapture("dotnet --version")) {
this._warn("😭 dotnet not found")
return
}

this._execInProc(`dotnet pack -c Release ${this.PROJECT_FILE_PATH} -o .`)
const NUGET_PUSH_RESPONSE = this._execAndCapture(`dotnet nuget push *.nupkg -s https://api.nuget.org/v3/index.json -k ${this.NUGET_KEY}`)
const NUGET_ERROR_REGEX = /(error: Response status code does not indicate success.*)/

if (NUGET_ERROR_REGEX.test(NUGET_PUSH_RESPONSE))
this._fail(`😭 ${NUGET_ERROR_REGEX.exec(NUGET_PUSH_RESPONSE)[1]}`)
}

_tagCommit(version) {
if (this.TAG_COMMIT) {
const TAG = this.TAG_FORMAT.replace("*", version)

if (this._execAndCapture(`git ls-remote --tags origin ${TAG}`).indexOf(TAG) >= 0) {
this._warn(`😢 tag ${TAG} already exists`)
return
}

this._execInProc(`git tag ${TAG}`)
this._execInProc(`git push origin ${TAG}`)
}
}

_pushAndTag(version, name) {
console.log(`👍 found a new version (${version}) of ${name}`)
this._tagCommit(version)
this._pushPackage()
}

run() {
if (!this.PROJECT_FILE_PATH)
this._fail("😭 project file not given")

this.PROJECT_FILE_PATH = this._resolveIfExists(this.PROJECT_FILE_PATH, "😭 project file not found")
this.VERSION_FILE_PATH = !this.VERSION_FILE_PATH ? this.PROJECT_FILE_PATH : this._resolveIfExists(this.VERSION_FILE_PATH, "😭 version file not found")

const FILE_CONTENT = fs.readFileSync(this.VERSION_FILE_PATH, { encoding: "utf-8" }),
VERSION_INFO = this.VERSION_REGEX.exec(FILE_CONTENT)

if (!VERSION_INFO)
this._fail("😢 unable to extract version info")

const CURRENT_VERSION = VERSION_INFO[1]

if (!this.PACKAGE_NAME)
this.PACKAGE_NAME = path.basename(this.PROJECT_FILE_PATH).split(".").slice(0, -1).join(".")

https.get(`https://api.nuget.org/v3-flatcontainer/${this.PACKAGE_NAME}/index.json`, res => {
let body = ""

if (res.statusCode == 404)
this._pushAndTag(CURRENT_VERSION, this.PACKAGE_NAME)

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(CURRENT_VERSION) < 0)
this._pushAndTag(CURRENT_VERSION, this.PACKAGE_NAME)
})
}
}).on("error", e => {
this._warn(`😢 error reaching nuget.org ${e.message}`)
})
}
}

new Action().run()

0 comments on commit dbb450e

Please sign in to comment.