Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .cursor/rules/yaml-checklist.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
globs: *.yml
alwaysApply: false
---

Moving stuff to Environment Variables for safer scripting
ex: there is an input named `githubTag`. Add an `ENV:` to it like `INPUTS_GITHUB_TAG: ${{ inputs.githubTag }}`

### shell scripts

In github worklows that run shell scripts refer to inputs and outputs via the environment variable convention.
BAD: `RESPONSE=$(npm view .@${{ inputs.githubTag }} version --json --silent || echo "Not published")`
GOOD: `RESPONSE=$(npm view .@$INPUTS_GITHUB_TAG version --json --silent || echo "Not published")`

### script tag

when using `script` from actions/github-script
BAD: `script: core.setFailed("The version '$INPUTS_GITHUB_TAG' has already been published to npm")`
GOOD: `script: core.setFailed(`The version '${process.env.INPUTS_GITHUB_TAG}' has already been published to npm`)`

It's OK to use ${{ foo }} outside of shell script (`run:`) blocks and outside of `script` (example if: statements on a job)
13 changes: 13 additions & 0 deletions .github/actions/npmInstallWithRetries/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: npm-install-with-retries
description: 'wraps npm install with retries/timeout to handle network failures'
inputs:
ignore-scripts:
default: 'false'
description: 'Skip pre/post install scripts'
runs:
using: composite
steps:
- name: npm install
uses: salesforcecli/github-workflows/.github/actions/retry@main
with:
command: npm install --timeout 600000 ${{ inputs.ignore-scripts == 'true' && '--ignore-scripts' || '' }}
4 changes: 2 additions & 2 deletions .github/actions/yarnInstallWithRetries/action.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: yarn-install-with-retries
description: "wraps yarn install with retries/timeout to handle network failures"
description: 'wraps yarn install with retries/timeout to handle network failures'
inputs:
ignore-scripts:
default: 'false'
description: "Skip pre/post install scripts"
description: 'Skip pre/post install scripts'
runs:
using: composite
steps:
Expand Down
22 changes: 11 additions & 11 deletions .github/workflows/externalNut.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,50 +15,50 @@ on:
inputs:
# could we get this from pjson?
packageName:
description: "The npm package that this repository publishes. ex: @salesforce/core"
description: 'The npm package that this repository publishes. ex: @salesforce/core'
required: true
type: string
externalProjectGitUrl:
description: "The url that will be cloned. This contains the NUTs you want to run. Ex: https://github.com/salesforcecli/plugin-user"
description: 'The url that will be cloned. This contains the NUTs you want to run. Ex: https://github.com/salesforcecli/plugin-user'
type: string
required: true
command:
required: false
type: string
default: yarn test:nuts
description: "command to execute (ex: yarn test:nuts)"
description: 'command to execute (ex: yarn test:nuts)'
nodeVersion:
required: false
description: version of node to run tests against. Use things like [lts/-1, lts/*, latest] to avoid hardcoding versions
type: string
default: lts/*
os:
required: false
description: "runs-on property, ex: ubuntu-latest, windows-latest"
description: 'runs-on property, ex: ubuntu-latest, windows-latest'
type: string
default: "ubuntu-latest"
default: 'ubuntu-latest'
sfdxExecutablePath:
required: false
description: "Path to sfdx executable to be used by NUTs, defaults to ''"
type: string
preBuildCommands:
required: false
description: "commands to run before the build...for example, to delete known module conflicts"
description: 'commands to run before the build...for example, to delete known module conflicts'
type: string
default: 'echo "no preBuildCommands passed"'
postBuildCommands:
required: false
description: "script to run after the build"
description: 'script to run after the build'
type: string
default: 'echo "no postBuildCommands passed"'
preExternalBuildCommands:
required: false
description: "commands to run before the build of the external repo...for example, to delete known module conflicts"
description: 'commands to run before the build of the external repo...for example, to delete known module conflicts'
type: string
default: 'echo "no preExternalBuildCommands passed"'
preSwapCommands:
required: false
description: "commands to run before ANY modifications happen. For example, changes that modify the lockfile like yarn add or remove need to happen before the action manually swaps the dependency under test"
description: 'commands to run before ANY modifications happen. For example, changes that modify the lockfile like yarn add or remove need to happen before the action manually swaps the dependency under test'
type: string
default: 'echo "no preSwapCommands passed"'
useCache:
Expand All @@ -73,10 +73,10 @@ on:
required: false
description: "branch to clone from the repo. Defaults to 'main'"
type: string
default: "main"
default: 'main'
ignoreScripts:
required: false
description: "if true, will run yarn install --ignore-scripts when building package in node_modules"
description: 'if true, will run yarn install --ignore-scripts when building package in node_modules'
type: boolean
default: false

Expand Down
40 changes: 26 additions & 14 deletions .github/workflows/npmPublish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,29 @@ on:
description: the github release tag that you want to publish as an npm package
required: true
type: string
packageManager:
description: the package manager to use. Defaults to yarn, but can be set to npm
required: false
default: yarn
type: string
jobs:
check-publish:
outputs:
published: ${{ steps.is-published.outputs.published }}
runs-on: ubuntu-latest
env:
INPUTS_GITHUB_TAG: ${{ inputs.githubTag }}
INPUTS_PACKAGE_MANAGER: ${{ inputs.packageManager }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, good idea to move these (non-secret envs) to the top level.

steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.githubTag }}

- name: Validate package manager
run: |
if [[ "$INPUTS_PACKAGE_MANAGER" != "yarn" && "$INPUTS_PACKAGE_MANAGER" != "npm" ]]; then
echo "Error: packageManager must be 'yarn' or 'npm', got '$INPUTS_PACKAGE_MANAGER'"
exit 1
fi
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.nodeVersion }}
Expand All @@ -76,7 +89,6 @@ jobs:
echo "published=false" >> "$GITHUB_OUTPUT"
fi
env:
INPUTS_GITHUB_TAG: ${{ inputs.githubTag }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- run: echo "[INFO] Is package published:\ $STEPS_IS_PUBLISHED_PUBLISHED"
Expand All @@ -88,8 +100,6 @@ jobs:
uses: actions/github-script@v7
with:
script: core.setFailed(`The version '${process.env.INPUTS_GITHUB_TAG}' has already been published to npm`)
env:
INPUTS_GITHUB_TAG: ${{ inputs.githubTag }}

ctc-open:
needs: [check-publish]
Expand All @@ -103,22 +113,26 @@ jobs:
needs: [check-publish, ctc-open]
if: ${{ always() && needs.check-publish.outputs.published == 'false' && (!inputs.ctc || (inputs.ctc && needs.ctc-open.outputs.changeCaseId)) }}
runs-on: ${{ inputs.runsOn }}
env:
INPUTS_PACKAGE_MANAGER: ${{ inputs.packageManager }}
INPUTS_GITHUB_TAG: ${{ inputs.githubTag }}
INPUTS_TAG: ${{ inputs.tag }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.githubTag }}

- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.nodeVersion }}
cache: yarn

- uses: salesforcecli/github-workflows/.github/actions/yarnInstallWithRetries@main

- run: yarn build

cache: ${{ inputs.packageManager }}
- name: Install dependencies with yarn
if: inputs.packageManager == 'yarn'
uses: salesforcecli/github-workflows/.github/actions/yarnInstallWithRetries@main
- name: Install dependencies with npm
if: inputs.packageManager == 'npm'
uses: salesforcecli/github-workflows/.github/actions/npmInstallWithRetries@main
- run: $INPUTS_PACKAGE_MANAGER run build
- run: npm install -g @salesforce/plugin-release-management

- name: NPM Release
run: |
sf-release npm:package:release \
Expand All @@ -129,8 +143,6 @@ jobs:
${{ inputs.prerelease && format('--prerelease {0}', github.ref_name) || '' }} \
${{ inputs.sign && '--sign' || '' }}
env:
INPUTS_GITHUB_TAG: ${{ inputs.githubTag }}
INPUTS_TAG: ${{ inputs.tag }}
NPM_TOKEN: ${{secrets.NPM_TOKEN}}
AWS_ACCESS_KEY_ID: ${{secrets.AWS_ACCESS_KEY_ID}}
AWS_SECRET_ACCESS_KEY: ${{secrets.AWS_SECRET_ACCESS_KEY}}
Expand Down
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ jobs:
# NPM_TOKEN: ^&*$
```

works with npm, too

```yml
with:
packageManager: npm
```

### Plugin Signing

Plugins created by Salesforce teams can be signed automatically with `sign:true` if the repo is in [salesforcecli](https://github.com/salesforcecli) or [forcedotcom](https://github.com/forcedotcom) gitub organization.
Expand Down Expand Up @@ -135,12 +142,12 @@ on:
# point at specific branches, or a naming convention via wildcard
- prerelease/**
tags-ignore:
- "*"
- '*'
workflow_dispatch:
inputs:
prerelease:
type: string
description: "Name to use for the prerelease: beta, dev, etc. NOTE: If this is already set in the package.json, it does not need to be passed in here."
description: 'Name to use for the prerelease: beta, dev, etc. NOTE: If this is already set in the package.json, it does not need to be passed in here.'

jobs:
release:
Expand Down Expand Up @@ -294,7 +301,7 @@ name: automerge
on:
workflow_dispatch:
schedule:
- cron: "56 2,5,8,11 * * *"
- cron: '56 2,5,8,11 * * *'

jobs:
automerge:
Expand Down