diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml new file mode 100644 index 0000000..944d1e5 --- /dev/null +++ b/.github/workflows/default.yml @@ -0,0 +1,27 @@ +name: Release + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + default: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - uses: actions/setup-node@v1 + with: + node-version: 14 + - name: Install dependencies + run: yarn + - name: Release package + run: npx semantic-release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.prettierignore b/.prettierignore index ec6d3cd..d1d769f 100755 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1,2 @@ package.json +/.vscode diff --git a/README.md b/README.md index 19aa29f..a90c63c 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,91 @@ # semantic-release-sfdx -Set of [semantic-release](https://github.com/semantic-release/semantic-release) plugins for publishing an SFDX package +> [semantic-release](https://github.com/semantic-release/semantic-release) plugin for publishing an SFDX package +## Prerequisites + +You must have SFDX installed and connected to your DevHub (see Authorization in the [Salesforce DX Developer Guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth.htm)). + +## Configuration + +To enable this plugin, simply add the following to your `package.json` or [release configuration file](https://semantic-release.gitbook.io/semantic-release/usage/configuration). ```json { "release": { - "verifyConditions": "semantic-release-sfdx", - "publish": { - "devhubusername": "MyDevHub" - } + "plugins": ["semantic-release-sfdx"] } } ``` -## Windows Support Disclaimer -Currently this plugin will only runs in *nix systems, as it uses shell scripts to log into google cloud. If you need Windows support Pull-requests are welcome. +### DevHub -## Configuration +By default this plugin uses the DevHub which is set in your `defaultdevhubusername` sfdx config. + +To use another DevHub, set the environment variable `SFDX_DEFAULTDEVHUBUSERNAME` (see [Salesforce CLI Setup Guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_dev_cli_env_variables.htm)). + +### Advanced Configuration -You must have SFDX installed and connected to your dev hub +**static config via `package.json`** -## Plugins +```json +{ + "release": { + "plugins": [ + [ + "semantic-release-sfdx", + { + "codecoverage": true, + "promote": true, + "installationkey": "mysecretkey" + } + ] + ] + } +} +``` + +**dynamic config via `release.config.js`** + +```javascript +module.exports = { + plugins: [ + [ + 'semantic-release-sfdx', + { + codecoverage: process.env.PROMOTE_PACKAGE_VERSION === 'true', + promote: process.env.PROMOTE_PACKAGE_VERSION === 'true', + installationkey: process.env.INSTALLATIONKEY, + }, + ], + ], +} +``` ### `verifyConditions` -Verify that all needed configuration is present and login to the dev hub +To disable the verification of your SFDX project, DevHub and installationkey: + +```json +{ + "release": { + "plugins": [ + "semantic-release-sfdx", + { + "verifyConditions": false + } + ] + } +} +``` + +## Example -### `publish` +See a second generation package being released with this plugin [here](https://github.com/mdapi-issues/managed-package-2nd-gen-dummy). -Tag the image specified by `name` with the new version, create ne package version and update the `latest` tag. +- [package.json](https://github.com/mdapi-issues/managed-package-2nd-gen-dummy/blob/main/.github/workflows/default.yml) +- [GitHub Actions configuration](https://github.com/mdapi-issues/managed-package-2nd-gen-dummy/blob/main/package.json) +## Credits -Thanks to https://github.com/carlos-cubas/semantic-release-gcp.git for kicking off point \ No newline at end of file +Thanks to https://github.com/carlos-cubas/semantic-release-gcp.git for kicking off point diff --git a/lib/prepare.js b/lib/prepare.js index 8fef13d..a2b2153 100755 --- a/lib/prepare.js +++ b/lib/prepare.js @@ -3,46 +3,59 @@ const sfdx = require('sfdx-node') const fs = require('fs') const _ = require('lodash') const path = require('path') -module.exports = async (pluginConfig, { nextRelease: { version }, logger }) => { - logger.log(`Creating new package version ${pluginConfig.name}:${version}`) - - const config = {} - config.jwtkeyfile = pluginConfig.jwtkeyfile || 'assets/server.key' - config.clientid = pluginConfig.clientid || process.env['SFDX_CLIENT_ID'] - config.username = pluginConfig.devHubUsername || process.env['SFDX_DEV_HUB_USERNAME'] +module.exports = async (pluginConfig, { nextRelease: { version }, logger }) => { + const packageVersion = `${version}.0` const project = JSON.parse(fs.readFileSync('sfdx-project.json')) const pkg = util.getPackage(project) - console.log(pkg) + logger.log(`Creating new package version ${pkg.package}:${packageVersion}`) + const versionCreateOptions = { + _rejectOnError: true, + path: pkg.path, + tag: version, + versionnumber: packageVersion, + json: true, + wait: pluginConfig.versionCreateWait || 15, + } + if (pluginConfig.installationkey) { + versionCreateOptions.installationkey = pluginConfig.installationkey + } else { + versionCreateOptions.installationkeybypass = true + } + if (pluginConfig.codecoverage) { + versionCreateOptions.codecoverage = true + } return sfdx.package - .versionCreate({ - path: pkg.path, - targetdevhubusername: config.username, - tag: `${version}.0`, - versionnumber: `${version}.0`, - json: true, - wait: pluginConfig.versionCreateWait || 15, - installationkeybypass: true, - }) + .versionCreate(versionCreateOptions) .then(res => { - if (!res) { - throw new Error('Error Creating Package Version') - } - return sfdx.package - .versionList({ - targetdevhubusername: config.username, + return sfdx.package.versionList().then(list => + _.find(list, { + SubscriberPackageVersionId: res.SubscriberPackageVersionId, }) - .then(list => - _.find(list, { - SubscriberPackageVersionId: res.SubscriberPackageVersionId, + ) + }) + .then(res => { + logger.log(`Package Version Create Result: ${JSON.stringify(res)}`) + if (pluginConfig.promote) { + logger.log('Promoting Package Version') + return sfdx.package + .versionPromote({ + _rejectOnError: true, + package: res.SubscriberPackageVersionId, + noprompt: true, + json: true, }) - ) + .then(() => { + return res + }) + } + return res }) .then(res => { logger.log('Generating README file') - const tmpl = fs.readFileSync(path.join(__dirname, '../', 'templates/Readme.tmpl')) + const tmpl = fs.readFileSync(path.join(__dirname, '..', 'templates', 'Readme.tmpl')) const readme = _.template(tmpl) fs.writeFileSync(pluginConfig.readmeFile || 'README.md', readme(res)) diff --git a/lib/util.js b/lib/util.js index 80813d2..586b866 100644 --- a/lib/util.js +++ b/lib/util.js @@ -1,15 +1,11 @@ const sfdx = require('sfdx-node') module.exports = { - getDefaultDevHub: (username) => { - if(username) return Promise.resolve({username: username}); + getDefaultDevHub: () => { return sfdx.org.list().then(orgs => { return orgs.nonScratchOrgs && orgs.nonScratchOrgs.find(org => org.isDefaultDevHubUsername) }) }, - jwtAuth: config => { - return sfdx.auth.jwtGrant(config) - }, getPackage: project => { return project.packageDirectories.find(dir => dir.default) }, diff --git a/lib/verify.js b/lib/verify.js index 77aa184..e94a6f9 100755 --- a/lib/verify.js +++ b/lib/verify.js @@ -2,43 +2,21 @@ const fs = require('fs') const util = require('./util') module.exports = async (pluginConfig, { logger }) => { - const config = {} - config.jwtkeyfile = pluginConfig.jwtkeyfile || 'assets/server.key' - config.clientid = pluginConfig.clientid || process.env['SFDX_CLIENT_ID'] - config.username = pluginConfig.devHubUsername || process.env['SFDX_DEV_HUB_USERNAME'] - if (!fs.existsSync('sfdx-project.json')) { throw new Error('This is not and sfdx project. Please make sure sfdx-project.json exists') } - if (!fs.existsSync(config.jwtkeyfile) && !process.env['SFDX_JWT_KEYFILE']) { - throw new Error( - `Server Key not found. Make sure jwtkeyfile or SFDX_JWT_KEYFILE var is set or server key is in assts/server.key file` - ) + if ( + (pluginConfig.installationkey instanceof String || typeof pluginConfig.installationkey === 'string') && + pluginConfig.installationkey.trim() === '' + ) { + throw new Error('The installationkey was specified but is empty') } - if (!config.clientid) { - throw new Error(`Client ID value not set in config at clientid or SFDX_CLIENT_ID env var`) - } - // check if default is set - return util - .getDefaultDevHub(config.username) - .then(defaultDevHub => { - if (!defaultDevHub) { - throw new Error(`Default dev hub not defined`) - } else { - config.username = defaultDevHub.username - } - }) - .then(() => { - return util.jwtAuth(config).then(res => { - if (res && res.orgId) { - logger.log(`Logged in to ${res.orgId} successfully.`) - } else { - throw new Error( - `Could not log in. Check client id and access has been granted. (see: https://salesforce.stackexchange.com/questions/184363/salesforce-jwt-user-hasnt-approved-this-consumer-again/184635)` - ) - } - }) - }) - + + // check if default is set + return util.getDefaultDevHub().then(defaultDevHub => { + if (!defaultDevHub) { + throw new Error(`Default dev hub not defined`) + } + }) } diff --git a/package.json b/package.json index d3babba..282f009 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "dependencies": { "@semantic-release/error": "^2.1.0", "lodash": "^4.17.11", - "sfdx-node": "^1.1.0" + "sfdx-node": "^2.2.0" }, "devDependencies": { "cz-conventional-changelog": "^2.0.0", @@ -83,5 +83,10 @@ }, "publishConfig": { "access": "public" + }, + "release": { + "branches": [ + "master" + ] } }