Skip to content
Closed
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
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
packages/**/node_modules
packages/**/dist
packages/zcli-connectors/src/templates
8 changes: 4 additions & 4 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ your PR is merged.

## Development Workflow

Before you start, be sure [yarn](https://yarnpkg.com/en/) is installed
on your system. After you clone this repo, run `yarn` to install
dependencies needed for development. After installation, the following
commands are available:
Before you start, be sure [Node.js](https://nodejs.org/) v20.17.0 or higher is installed
on your system. The project uses Yarn Berry (v4) which is managed via Corepack (included with Node.js).
After you clone this repo, run `yarn` to install dependencies needed for development.
After installation, the following commands are available:

- `yarn dev` to run zcli
- `yarn lint` to lint your typescript code using standardjs eslint config
Expand Down
56 changes: 56 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Release to npm

# ⚠️ SAFETY MODE: This workflow is configured with --dry-run by default
# ⚠️ No packages will actually be published until you remove the --dry-run flag
# ⚠️ See line ~46 in the 'publish' job

on:
push:
branches:
- master
paths:
- 'lerna.json'
- 'packages/*/package.json'

jobs:
check-release:
name: Check if release commit
runs-on: ubuntu-latest
outputs:
should-publish: ${{ steps.check.outputs.should-publish }}
version: ${{ steps.check.outputs.version }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2

- name: Check if this is a release commit
id: check
run: |
COMMIT_MSG=$(git log -1 --pretty=%B)
if echo "$COMMIT_MSG" | grep -q "chore(release): publish"; then
echo "should-publish=true" >> $GITHUB_OUTPUT
VERSION=$(jq -r '.version' lerna.json)
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "βœ… Release commit detected: $VERSION"
else
echo "should-publish=false" >> $GITHUB_OUTPUT
echo "ℹ️ Not a release commit, skipping publish"
fi

publish:
Comment on lines +17 to +41

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 3 days ago

In general, the fix is to explicitly specify permissions for the workflow or for each job so that the GITHUB_TOKEN has only the scopes required. For this workflow, the check-release job just needs to read repository contents (for actions/checkout and lerna.json), so contents: read is sufficient. The publish job is a reusable workflow call; its required permissions should be defined inside that reusable workflow, so this caller does not need to grant additional permissions to it.

The best minimal fix without changing behavior is to add a top-level permissions: block right under the name: (or before on:) that sets contents: read. This will apply to all jobs in this workflow that do not define their own permissions: block, covering both check-release and publish without altering their existing logic. No imports or additional methods are needed; this is purely a YAML configuration change within .github/workflows/release.yml, around lines 1–7.

Suggested changeset 1
.github/workflows/release.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -4,6 +4,9 @@
 # ⚠️ No packages will actually be published until you remove the --dry-run flag
 # ⚠️ See line ~46 in the 'publish' job
 
+permissions:
+  contents: read
+
 on:
   push:
     branches:
EOF
@@ -4,6 +4,9 @@
# ⚠️ No packages will actually be published until you remove the --dry-run flag
# ⚠️ See line ~46 in the 'publish' job

permissions:
contents: read

on:
push:
branches:
Copilot is powered by AI and may make mistakes. Always verify output.
name: Publish packages to npm
needs: check-release
if: needs.check-release.outputs.should-publish == 'true'
# TODO: Update this path to your actual company reusable workflow location
# Example: zendesk/shared-workflows/.github/workflows/npm-publish.yml@main
uses: zendesk/REPLACE_WITH_ACTUAL_PATH/.github/workflows/npm-publish.yml@main
with:
node_version: '20.17.0'
# This command will be executed as: yarn workspaces foreach ... npm publish --otp $totp
# ⚠️ IMPORTANT: Remove --dry-run flag when ready for production publishing!
command: 'workspaces foreach --no-private --topological npm publish --dry-run --tolerate-republish'
commit: false
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_TOTP_DEVICE: ${{ secrets.NPM_TOTP_DEVICE }}
Comment on lines +42 to +56

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {}

Copilot Autofix

AI 5 days ago

In general, fix this by explicitly declaring a minimal permissions block for the workflow or individual jobs, instead of relying on repository defaults. For a read-only analysis/check job, contents: read is usually sufficient. For the publish job that calls a reusable workflow, we should not guess its write needs here; instead, we can leave permissions determination to the reusable workflow, which will have its own permissions block. GitHub allows a calling workflow to omit permissions for a uses: job and still rely on the callee’s permissions declaration.

The best targeted fix without changing functionality is:

  • Add a permissions block at the top level of the workflow (applies to all jobs by default) setting contents: read. This covers the check-release job, which only reads the repo.
  • Add an explicit empty permissions: {} block on the publish job. For a job that uses a reusable workflow, this means β€œdo not grant additional permissions here; let the called workflow define what it needs.” This satisfies CodeQL’s requirement that every job has an explicit permissions block, while not constraining the reusable workflow’s own permissions.

Concretely, in .github/workflows/release.yml:

  • Insert, after name: Release to npm and before on:, a root-level permissions: block:
permissions:
  contents: read
  • Add a permissions: {} line inside the publish job (aligned with needs, if, uses, etc.), so that job explicitly declares that it does not add any token permissions itself.

No imports or external methods are needed; this is pure YAML configuration.

Suggested changeset 1
.github/workflows/release.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -4,6 +4,9 @@
 # ⚠️ No packages will actually be published until you remove the --dry-run flag
 # ⚠️ See line ~46 in the 'publish' job
 
+permissions:
+  contents: read
+
 on:
   push:
     branches:
@@ -42,6 +45,7 @@
     name: Publish packages to npm
     needs: check-release
     if: needs.check-release.outputs.should-publish == 'true'
+    permissions: {}
     # TODO: Update this path to your actual company reusable workflow location
     # Example: zendesk/shared-workflows/.github/workflows/npm-publish.yml@main
     uses: zendesk/REPLACE_WITH_ACTUAL_PATH/.github/workflows/npm-publish.yml@main
EOF
@@ -4,6 +4,9 @@
# ⚠️ No packages will actually be published until you remove the --dry-run flag
# ⚠️ See line ~46 in the 'publish' job

permissions:
contents: read

on:
push:
branches:
@@ -42,6 +45,7 @@
name: Publish packages to npm
needs: check-release
if: needs.check-release.outputs.should-publish == 'true'
permissions: {}
# TODO: Update this path to your actual company reusable workflow location
# Example: zendesk/shared-workflows/.github/workflows/npm-publish.yml@main
uses: zendesk/REPLACE_WITH_ACTUAL_PATH/.github/workflows/npm-publish.yml@main
Copilot is powered by AI and may make mistakes. Always verify output.
17 changes: 6 additions & 11 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,19 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: zendesk/checkout@v3
- name: Enable Corepack
run: corepack enable || true
- name: Use Node.js
uses: zendesk/setup-node@v4
with:
node-version: "${{ matrix.node-version }}"
cache: "yarn"
- uses: zendesk/cache@v3
with:
path: |
./node_modules/
./packages/zcli/node_modules/
./packages/zcli-core/node_modules/
./packages/zcli-apps/node_modules/
./packages/zcli-themes/node_modules/
key: node-modules-${{ runner.os }}-${{ hashFiles('**/package.json') }}-${{ hashFiles('yarn.lock') }}
path: .yarn/cache
key: yarn-berry-${{ runner.os }}-${{ hashFiles('yarn.lock', '.yarnrc.yml') }}
restore-keys: |
node-modules-${{ runner.os }}-${{ hashFiles('**/package.json') }}-
node-modules-${{ runner.os }}-
- run: yarn install
yarn-berry-${{ runner.os }}-
- run: yarn install --immutable
- run: yarn lint
- run: yarn test
- run: yarn test:functional
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ packages/zcli-apps/tests/functional/mocks/*/tmp
packages/**/dist
.DS_Store
.idea

# Yarn Berry
.yarn/*
!.yarn/releases
IMPLEMENTATION_GUIDE.md
.tool-versions
5 changes: 4 additions & 1 deletion .mocharc.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@
"watch-ignore": ["lib/vendor"],
"require": ["ts-node/register"],
"recursive": true,
"ignore": ["packages/zcli-connectors/src/templates/**"]
"ignore": [
"packages/zcli-connectors/src/templates/**",
"packages/zcli-connectors/src/**/*.test.ts"
]
}
934 changes: 934 additions & 0 deletions .yarn/releases/yarn-4.5.3.cjs

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
nodeLinker: node-modules

enableGlobalCache: false

supportedArchitectures:
os: ["linux", "darwin", "win32"]
cpu: ["x64", "arm64"]

yarnPath: .yarn/releases/yarn-4.5.3.cjs
175 changes: 175 additions & 0 deletions AUTOMATED_RELEASE_CHECKLIST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# Automated Release Setup Checklist

This checklist tracks the setup of the automated release process for ZCLI.

## βœ… Completed Steps

- [x] Migrate to Yarn Berry v4.5.3
- [x] Add `build` script to root package.json
- [x] Create `scripts/create-release-pr.sh`
- [x] Create `.github/workflows/release.yml`
- [x] Update `scripts/release.sh` with deprecation notice
- [x] Create release process documentation

## πŸ”§ TODO: Configuration Required

### 1. Update Workflow Path (Required)

**File:** `.github/workflows/release.yml`

**Action:** Replace the placeholder with your actual company workflow path

```yaml
# Current (line ~40):
uses: zendesk/REPLACE_WITH_ACTUAL_PATH/.github/workflows/npm-publish.yml@main

# Replace with actual path (ask platform team):
uses: zendesk/shared-workflows/.github/workflows/npm-publish.yml@main
```

**Who to ask:** Platform/DevOps team for the reusable workflow location

---

### 2. Configure GitHub Secrets (Required)

**Location:** Repository Settings β†’ Secrets and variables β†’ Actions

**Secrets to add:**

#### `NPM_TOKEN`
- **What:** npm authentication token
- **How to get:**
1. Log into npm: https://www.npmjs.com/
2. Go to: Settings β†’ Access Tokens
3. Generate New Token β†’ Automation
4. Copy token (starts with `npm_`)
5. Add to GitHub secrets

#### `NPM_TOTP_DEVICE`
- **What:** TOTP secret for npm 2FA (base32 encoded)
- **How to get:**
1. Go to npm 2FA settings
2. Disable 2FA (if enabled)
3. Re-enable 2FA
4. Click "Can't scan? Enter this code manually"
5. Copy the base32 secret (e.g., `JBSWY3DPEHPK3PXP`)
6. Add to GitHub secrets
7. Update your authenticator app with the new secret

**Status:** ⬜ Not configured yet

---

### 3. Test with Dry Run (Recommended)

The workflow is configured with `--dry-run` flag by default for safety.

**Status:** βœ… Already configured (dry-run is the default)

#### Step 3a: Create test release

```bash
# Create test commit with conventional commit message
git checkout -b test-release-workflow
echo "# Test" >> README.md
git add README.md
git commit -m "feat: test automated release workflow"
git push origin test-release-workflow

# Merge to master (or create PR and merge)
# Then run:
./scripts/create-release-pr.sh
```

#### Step 3b: Merge and verify

1. Merge the release PR
2. Go to Actions tab: https://github.com/zendesk/zcli/actions
3. Watch "Release to npm" workflow run
4. Verify it completes without errors
5. Confirm nothing was published to npm (dry-run mode)

**Status:** ⬜ Not tested yet

---

### 4. Enable Production Publishing (Required)

After successful dry-run test, enable real publishing:

**File:** `.github/workflows/release.yml`

**Remove the `--dry-run` flag:**
```yaml
# Change from:
command: 'workspaces foreach --no-private --topological npm publish --dry-run --tolerate-republish'

# To:
command: 'workspaces foreach --no-private --topological npm publish --tolerate-republish'
# ^^^^^^^^^^^ Remove this
```

**Status:** ⬜ Still in dry-run mode

---

### 5. Update Team Documentation (Optional)

- [ ] Update internal wiki/confluence with new process
- [ ] Notify team about the new release workflow
- [ ] Add link to [docs/RELEASING.md](./docs/RELEASING.md) in onboarding docs

---

## πŸ“š Documentation

| Document | Purpose |
|----------|---------|
| [docs/SETUP_RELEASE_WORKFLOW.md](./docs/SETUP_RELEASE_WORKFLOW.md) | Detailed setup instructions |
| [docs/RELEASING.md](./docs/RELEASING.md) | How to create releases |
| [scripts/create-release-pr.sh](./scripts/create-release-pr.sh) | Release PR creation script |
| [.github/workflows/release.yml](./.github/workflows/release.yml) | GitHub Actions workflow |

---

## πŸš€ Quick Start (After Setup)

Once everything above is configured:

```bash
# 1. Run the release script
./scripts/create-release-pr.sh

# 2. Open the PR URL provided

# 3. Review and merge

# 4. Automated publishing happens!
```

---

## ❓ Getting Help

**Questions about:**
- Reusable workflow path β†’ Ask platform/DevOps team
- npm credentials β†’ Ask maintainer with npm access
- Process/bugs β†’ Open issue in this repo

**Common issues:** See [Troubleshooting section](./docs/SETUP_RELEASE_WORKFLOW.md#troubleshooting) in setup docs

---

## βœ… Ready to Go Live?

Check that all items above are completed:

- [ ] Workflow path updated
- [ ] GitHub secrets configured
- [ ] Dry-run test passed
- [ ] Team notified

Once all checked, you're ready to create your first automated release! πŸŽ‰

⚠️ **Remember:** The workflow is in dry-run mode by default. After testing, don't forget to remove the `--dry-run` flag to enable real publishing!
Loading
Loading