From 48f9ae16d60d3e2badc51ce1fcdd9e338b91d70e Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Wed, 22 Oct 2025 10:19:42 -0400 Subject: [PATCH 01/10] robo start, need to review --- .circleci/config.yml | 187 ----------------------- .github/MIGRATION_SUMMARY.md | 125 +++++++++++++++ .github/workflows/automerge.yml | 2 +- .github/workflows/deploy-production.yml | 52 +++++++ .github/workflows/publish-production.yml | 57 +++++++ README.md | 4 +- nx.json | 4 +- 7 files changed, 239 insertions(+), 192 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 .github/MIGRATION_SUMMARY.md create mode 100644 .github/workflows/deploy-production.yml create mode 100644 .github/workflows/publish-production.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 21f47d1ef94..00000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,187 +0,0 @@ -version: 2.1 -orbs: - queue: eddiewebb/queue@1.5.0 - -references: - default_env: &default_env - docker: - - image: cimg/node:22.13.1 - working_directory: ~/repo - environment: - IGNORE_COMMIT_MESSAGE: 'chore(release): publish' - NODE_OPTIONS: '--max_old_space_size=8196' - CIRCLE_TEST_REPORTS: /tmp/test-results - NX_CLOUD: false - - yarn_cache_key_1: &yarn_cache_key_1 v2-yarn-{{ arch }}-{{ checksum "yarn.lock" }} - - webpack_cache_key_1: &webpack_cache_key_1 v1-webpack-{{ arch }}-{{ checksum "yarn.lock" }}-{{ .Branch }}-{{ .Revision }} - webpack_cache_key_2: &webpack_cache_key_2 v1-webpack-{{ arch }}-{{ checksum "yarn.lock" }}-{{ .Branch }} - - nx_cache_key_1: &nx_cache_key_1 v2-nx-{{ arch }}-{{ checksum "yarn.lock" }}-{{ .Branch }}-{{ epoch }} - nx_cache_key_2: &nx_cache_key_2 v2-nx-{{ arch }}-{{ checksum "yarn.lock" }}-{{ .Branch }} - nx_cache_key_3: &nx_cache_key_3 v2-nx-{{ arch }}-{{ checksum "yarn.lock" }} - - restore_yarn_cache: &restore_yarn_cache - restore_cache: - keys: - - *yarn_cache_key_1 - - save_yarn_cache: &save_yarn_cache - save_cache: - key: *yarn_cache_key_1 - paths: - - ~/.cache/yarn - - restore_webpack_cache: &restore_webpack_cache - restore_cache: - keys: - - *webpack_cache_key_1 - - *webpack_cache_key_2 - - save_webpack_cache: &save_webpack_cache - save_cache: - key: *webpack_cache_key_1 - paths: - - node_modules/.cache - - packages/styleguide/node_modules/.cache - - save_nx_cache: &save_nx_cache - save_cache: - key: *nx_cache_key_1 - paths: - - node_modules/.cache/nx - - restore_nx_cache: &restore_nx_cache - restore_cache: - keys: - - *nx_cache_key_1 - - *nx_cache_key_2 - - *nx_cache_key_3 - - save_node_modules: &save_node_modules - persist_to_workspace: - root: ~/repo - paths: - - node_modules - - packages - - restore_node_modules: &restore_node_modules - attach_workspace: #The attach_workspace copies and re-creates the entire workspace content when it runs. - at: ~/repo - - build_all_packages: &build_all_packages - run: - name: Build All Packages - command: yarn build - - set_git_user: &set_git_user # move to yarn action maybe - run: - name: Set git user - command: | - git config --global user.email "dev@codecademy.com" - git config --global user.name "codecademydev" - git config --global push.default current - - set_npm_token: &set_npm_token - run: - name: Add NPM auth token file - command: echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" > .npmrc - - skip_on_automated_commit: &skip_on_automated_commit - run: - name: Skip build from automated commit - command: | - export COMMIT_MESSAGE=$(git log --format=oneline -n 1 $CIRCLE_SHA1) - echo "Build started due to commit with message $COMMIT_MESSAGE, blocking builds started by ${IGNORE_COMMIT_MESSAGE}" - if [[ $COMMIT_MESSAGE == *"${IGNORE_COMMIT_MESSAGE}"* ]] ; then circleci-agent step halt ; fi - - skip_if_not_pr: &skip_if_not_pr - run: - name: Ensure workflow is associated with a pull request - command: | - prNumber="${CIRCLE_PR_NUMBER:-${CIRCLE_PULL_REQUEST##*/}}" - - if [[ -z "${prNumber}" ]]; then - echo "This workflow is not associated with a pull request; halting" - circleci-agent step halt - fi - -jobs: - checkout_code: - <<: *default_env - steps: - - checkout # circle keyword - - *set_npm_token - - *restore_yarn_cache - - run: yarn --production=false --frozen-lockfile - - *save_yarn_cache - - *save_node_modules - - publish: - <<: *default_env - resource_class: large - steps: - - *skip_on_automated_commit - - *set_git_user - - checkout - - *restore_node_modules - - *set_npm_token - - *restore_nx_cache - - *build_all_packages - - *save_nx_cache - - run: - name: Lerna Publish - command: yarn lerna publish --yes --exact --conventional-commits --changelog-preset conventionalcommits --include-merged-tags --create-release=github - - deploy: - <<: *default_env - resource_class: large - steps: - - *skip_on_automated_commit - - *set_git_user - - checkout - - *restore_node_modules - - *restore_nx_cache - - *restore_webpack_cache - - *build_all_packages - - run: - name: build storybook - command: yarn nx run styleguide:build-storybook - - run: - name: deploy - command: yarn deploy - - *save_nx_cache - - *save_webpack_cache - -workflows: - version: 2 - build-test: - jobs: - - queue/block_workflow: - only-on-branch: main - time: '10' - - checkout_code: - requires: - - queue/block_workflow - - publish: - requires: - - checkout_code - filters: - branches: - only: main - - deploy: - jobs: - - queue/block_workflow: - only-on-branch: main - time: '10' - - checkout_code: - requires: - - queue/block_workflow - - deploy: - requires: - - checkout_code - filters: - branches: - only: main diff --git a/.github/MIGRATION_SUMMARY.md b/.github/MIGRATION_SUMMARY.md new file mode 100644 index 00000000000..63692c5b0b6 --- /dev/null +++ b/.github/MIGRATION_SUMMARY.md @@ -0,0 +1,125 @@ +# CircleCI to GitHub Actions Migration Summary + +This document summarizes the migration from CircleCI to GitHub Actions completed on October 21, 2025. + +## New GitHub Actions Workflows Created + +### 1. `publish-production.yml` + +- **Purpose**: Publishes production packages to npm when changes are merged to main +- **Trigger**: Push to main branch +- **Key Features**: + - Skips automated release commits to prevent circular builds + - Uses Lerna for conventional commit-based versioning + - Creates GitHub releases automatically + - Uses concurrency control to prevent simultaneous publish jobs + +### 2. `deploy-production.yml` + +- **Purpose**: Deploys production Storybook to GitHub Pages when changes are merged to main +- **Trigger**: Push to main branch +- **Key Features**: + - Builds all packages and Storybook + - Deploys to GitHub Pages using gh-pages + - Uses concurrency control to prevent simultaneous deploy jobs + - Skips automated release commits + +## Files Modified + +### 1. `.github/workflows/automerge.yml` + +- **Change**: Updated CircleCI check reference from `build-test` to `test` +- **Reason**: The test suite is now run via GitHub Actions workflow named "Test Suite" with job name "test" + +### 2. `README.md` + +- **Changes**: + - Replaced CircleCI badge with GitHub Actions badge + - Updated publishing documentation to reference GitHub Actions instead of CircleCI + +### 3. `nx.json` + +- **Change**: Updated `ci` named input to reference GitHub Actions workflows +- **Before**: Referenced `.circleci/config.yml` and `.github/push.yml` +- **After**: References `.github/workflows/**/*.yml` and `.github/actions/**/*.yml` +- **Impact**: Nx will now properly invalidate caches when any GitHub Actions workflow or action changes + +## Files Deleted + +### 1. `.circleci/` directory + +- **Removed**: Entire CircleCI configuration directory +- **Reason**: All workflows have been successfully migrated to GitHub Actions + +## Workflow Comparison + +| CircleCI Job | GitHub Actions Workflow | Status | +| --------------- | ------------------------------------ | ----------- | +| `checkout_code` | Integrated into individual workflows | ✅ Migrated | +| `publish` | `publish-production.yml` | ✅ Migrated | +| `deploy` | `deploy-production.yml` | ✅ Migrated | + +## Key Design Decisions + +### 1. **DRY Principles** + +All workflows reuse the existing composite actions in `.github/actions/`: + +- `yarn/` - Node.js setup and dependency installation +- `set-git-user/` - Git user configuration +- `set-npm-token/` - NPM authentication +- `skip-automated-commits/` - Skip release commits +- `validate-pr-context/` - Ensure PR context exists + +### 2. **Concurrency Control** + +Replaced CircleCI's queue orb with GitHub Actions concurrency groups: + +- `publish-production` - Ensures only one publish runs at a time +- `deploy-production` - Ensures only one deploy runs at a time +- Both set `cancel-in-progress: false` to avoid canceling active deployments + +### 3. **Consistent Patterns** + +Followed patterns established in existing workflows: + +- Same Node.js version (`22.13.1`) +- Same runner (`ubuntu-22.04`) +- Same environment variables +- Same timeout settings (30 minutes) +- Same permissions structure + +### 4. **Security Best Practices** + +- Minimal permissions using principle of least privilege +- Separate tokens for different purposes (`ACTIONS_GITHUB_TOKEN` vs `NODE_AUTH_TOKEN`) +- Explicit permission declarations for each workflow + +## Testing Checklist + +Before considering this migration complete, verify: + +- [ ] Merge a PR to main and confirm packages are published correctly +- [ ] Verify GitHub releases are created with proper changelog +- [ ] Confirm Storybook deploys to GitHub Pages successfully +- [ ] Check that automerge still works with the new test check name +- [ ] Verify concurrency controls prevent overlapping publishes/deploys +- [ ] Ensure skip-automated-commits properly prevents circular builds + +## Secrets Required + +Ensure the following secrets are configured in GitHub: + +- `ACTIONS_GITHUB_TOKEN` - For creating releases and pushing to gh-pages +- `NODE_AUTH_TOKEN` - For publishing to npm +- Other existing secrets used by other workflows + +## Rollback Plan + +If issues arise, you can temporarily: + +1. Restore `.circleci/config.yml` from git history +2. Re-enable CircleCI in the repository settings +3. Update the automerge workflow to reference `build-test` again + +However, this should only be done as a last resort. Most issues can be fixed by updating the new workflows. diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 57fc3cca7e0..19a488408af 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -25,7 +25,7 @@ jobs: id: wait-for-build with: token: ${{ secrets.ACTIONS_GITHUB_TOKEN }} - checkName: build-test + checkName: test ref: ${{ github.event.pull_request.head.sha || github.sha }} timeoutSeconds: 1200 intervalSeconds: 30 diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml new file mode 100644 index 00000000000..5d694723e68 --- /dev/null +++ b/.github/workflows/deploy-production.yml @@ -0,0 +1,52 @@ +name: Deploy Production Storybook + +on: + push: + branches: + - main + +env: + NODE_VERSION: '22.13.1' + NODE_OPTIONS: '--max_old_space_size=8196' + NX_CLOUD: false + IGNORE_COMMIT_MESSAGE: 'chore(release): publish' + +permissions: + id-token: write + contents: write + +concurrency: + group: deploy-production + cancel-in-progress: false + +jobs: + deploy: + runs-on: ubuntu-22.04 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.ACTIONS_GITHUB_TOKEN }} + + - name: Skip build from automated commit + uses: ./.github/actions/skip-automated-commits + with: + ignore-commit-message: ${{ env.IGNORE_COMMIT_MESSAGE }} + + - name: Setup and Build + uses: ./.github/actions/yarn + + - name: Set git user + uses: ./.github/actions/set-git-user + + - name: Build All Packages + run: yarn build + + - name: Build Storybook + run: yarn nx run styleguide:build-storybook + + - name: Deploy to GitHub Pages + run: yarn deploy + env: + GITHUB_TOKEN: ${{ secrets.ACTIONS_GITHUB_TOKEN }} diff --git a/.github/workflows/publish-production.yml b/.github/workflows/publish-production.yml new file mode 100644 index 00000000000..6a3e9b17deb --- /dev/null +++ b/.github/workflows/publish-production.yml @@ -0,0 +1,57 @@ +name: Publish Production + +on: + push: + branches: + - main + +env: + NODE_VERSION: '22.13.1' + NODE_OPTIONS: '--max_old_space_size=8196' + NX_CLOUD: false + IGNORE_COMMIT_MESSAGE: 'chore(release): publish' + +permissions: + id-token: write + contents: write + pull-requests: write + issues: write + +concurrency: + group: publish-production + cancel-in-progress: false + +jobs: + publish: + runs-on: ubuntu-22.04 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.ACTIONS_GITHUB_TOKEN }} + + - name: Skip build from automated commit + uses: ./.github/actions/skip-automated-commits + with: + ignore-commit-message: ${{ env.IGNORE_COMMIT_MESSAGE }} + + - name: Setup and Build + uses: ./.github/actions/yarn + + - name: Set git user + uses: ./.github/actions/set-git-user + + - name: Set npm token + uses: ./.github/actions/set-npm-token + with: + token-secret: ${{ secrets.NODE_AUTH_TOKEN }} + + - name: Build All Packages + run: yarn build + + - name: Lerna Publish + run: yarn lerna publish --yes --exact --conventional-commits --changelog-preset conventionalcommits --include-merged-tags --create-release=github + env: + GH_TOKEN: ${{ secrets.ACTIONS_GITHUB_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} diff --git a/README.md b/README.md index 39b48d28459..0d9999af725 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ _The component library & design system for Codecademy._ ✨ --- -[![CircleCI](https://circleci.com/gh/Codecademy/gamut.svg?style=svg&circle-token=3d9adfca5a8b44e7297ceb18e032e89a11d223a2)](https://circleci.com/gh/Codecademy/gamut) +[![GitHub Actions](https://github.com/Codecademy/gamut/workflows/Test%20Suite/badge.svg)](https://github.com/Codecademy/gamut/actions) This repository is a monorepo that we manage using [Lerna](https://lerna.js.org/). That means that we publish several packages to npm from the same codebase, including: @@ -70,7 +70,7 @@ We provide a single package to manage the versions of a few core dependencies: ` 1. After your code has been reviewed and tested, you can merge your branch into main. 1. Make sure to update your PR title and add a short description of your changes for the changelog (see the [PR Title Guide](https://github.com/Codecademy/gamut#pr-title-guide)) 1. To merge your changes, add the `Ship It` label to your Pull Request. -1. Once your branch is merged into main, it will be published automatically by CircleCI. +1. Once your branch is merged into main, it will be published automatically by GitHub Actions. 1. You can find the new version number on npmjs.com/package/, or find it in that package's `package.json` on the `main` branch ### Publishing an alpha version of a module diff --git a/nx.json b/nx.json index 5cb7684ff3e..db61cdd4b0c 100644 --- a/nx.json +++ b/nx.json @@ -17,8 +17,8 @@ "namedInputs": { "babelConfig": ["{workspaceRoot}/babel.defaults.js"], "ci": [ - "{workspaceRoot}/.circleci/config.yml", - "{workspaceRoot}/.github/push.yml" + "{workspaceRoot}/.github/workflows/**/*.yml", + "{workspaceRoot}/.github/actions/**/*.yml" ], "default": ["{projectRoot}/**/*"], "production": [ From 54c6644e2599fac902faaa268c0eaa65ce2d77e3 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Wed, 22 Oct 2025 16:24:33 -0400 Subject: [PATCH 02/10] add back cacheing --- .github/MIGRATION_SUMMARY.md | 33 +++++++++++++++++++++++- .github/actions/yarn/action.yml | 1 + .github/workflows/deploy-production.yml | 21 +++++++++++++++ .github/workflows/publish-production.yml | 10 +++++++ 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/.github/MIGRATION_SUMMARY.md b/.github/MIGRATION_SUMMARY.md index 63692c5b0b6..b7b5eb6a945 100644 --- a/.github/MIGRATION_SUMMARY.md +++ b/.github/MIGRATION_SUMMARY.md @@ -89,7 +89,38 @@ Followed patterns established in existing workflows: - Same timeout settings (30 minutes) - Same permissions structure -### 4. **Security Best Practices** +### 4. **Caching Strategy** + +All workflows include comprehensive caching to speed up builds, matching CircleCI's strategy: + +**Yarn dependencies** (via `yarn` action): + +- Cached automatically by `setup-node` action using `cache: 'yarn'` +- Cache key based on `yarn.lock` hash +- Equivalent to CircleCI's yarn cache + +**Nx build cache** (in production workflows): + +- Path: `node_modules/.cache/nx` +- Primary key: `nx-{OS}-{yarn.lock}-{branch}-{run_id}` (similar to CircleCI's epoch-based key) +- Restore keys fall back progressively: branch → yarn.lock → OS +- Uses standard `actions/cache@v4` which automatically saves on success + +**Webpack cache** (in deploy workflow): + +- Paths: `node_modules/.cache` and `packages/styleguide/node_modules/.cache` +- Primary key: `webpack-{OS}-{yarn.lock}-{branch}-{commit_sha}` (matches CircleCI's revision-based key) +- Restore keys fall back to branch and yarn.lock levels +- Only included in deploy workflow since it's specifically needed for Storybook builds + +**Key improvements over CircleCI:** + +- Uses GitHub Actions' native `actions/cache@v4` (simpler than separate restore/save) +- Automatic cache saving (no need for `if: always()` conditions) +- `github.run_id` for Nx provides unique per-run keys similar to CircleCI's `{{ epoch }}` +- `github.sha` for webpack matches CircleCI's `{{ .Revision }}` + +### 5. **Security Best Practices** - Minimal permissions using principle of least privilege - Separate tokens for different purposes (`ACTIONS_GITHUB_TOKEN` vs `NODE_AUTH_TOKEN`) diff --git a/.github/actions/yarn/action.yml b/.github/actions/yarn/action.yml index 67e2ac6109d..f8f7f870a44 100644 --- a/.github/actions/yarn/action.yml +++ b/.github/actions/yarn/action.yml @@ -8,6 +8,7 @@ runs: uses: actions/setup-node@3235b876344d2a9aa001b8d1453c930bba69e610 with: node-version-file: .nvmrc + cache: 'yarn' - name: Install dependencies shell: bash diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml index 5d694723e68..c2fe707f54d 100644 --- a/.github/workflows/deploy-production.yml +++ b/.github/workflows/deploy-production.yml @@ -37,6 +37,27 @@ jobs: - name: Setup and Build uses: ./.github/actions/yarn + - name: Cache Nx + uses: actions/cache@v4 + with: + path: node_modules/.cache/nx + key: nx-${{ runner.os }}-${{ hashFiles('yarn.lock') }}-${{ github.ref_name }}-${{ github.run_id }} + restore-keys: | + nx-${{ runner.os }}-${{ hashFiles('yarn.lock') }}-${{ github.ref_name }}- + nx-${{ runner.os }}-${{ hashFiles('yarn.lock') }}- + nx-${{ runner.os }}- + + - name: Cache webpack + uses: actions/cache@v4 + with: + path: | + node_modules/.cache + packages/styleguide/node_modules/.cache + key: webpack-${{ runner.os }}-${{ hashFiles('yarn.lock') }}-${{ github.ref_name }}-${{ github.sha }} + restore-keys: | + webpack-${{ runner.os }}-${{ hashFiles('yarn.lock') }}-${{ github.ref_name }}- + webpack-${{ runner.os }}-${{ hashFiles('yarn.lock') }}- + - name: Set git user uses: ./.github/actions/set-git-user diff --git a/.github/workflows/publish-production.yml b/.github/workflows/publish-production.yml index 6a3e9b17deb..c7b39d99386 100644 --- a/.github/workflows/publish-production.yml +++ b/.github/workflows/publish-production.yml @@ -39,6 +39,16 @@ jobs: - name: Setup and Build uses: ./.github/actions/yarn + - name: Cache Nx + uses: actions/cache@v4 + with: + path: node_modules/.cache/nx + key: nx-${{ runner.os }}-${{ hashFiles('yarn.lock') }}-${{ github.ref_name }}-${{ github.run_id }} + restore-keys: | + nx-${{ runner.os }}-${{ hashFiles('yarn.lock') }}-${{ github.ref_name }}- + nx-${{ runner.os }}-${{ hashFiles('yarn.lock') }}- + nx-${{ runner.os }}- + - name: Set git user uses: ./.github/actions/set-git-user From 9a97cd95ed22f7b4be15a8ea212fda3bd853ac1b Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Thu, 23 Oct 2025 09:45:55 -0400 Subject: [PATCH 03/10] more automerge to required checks --- .github/workflows/automerge.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml index 19a488408af..670b8282483 100644 --- a/.github/workflows/automerge.yml +++ b/.github/workflows/automerge.yml @@ -20,15 +20,6 @@ jobs: runs-on: ubuntu-latest if: github.ref != 'refs/heads/main' steps: - - name: Wait for CI build - uses: fountainhead/action-wait-for-check@v1.0.0 - id: wait-for-build - with: - token: ${{ secrets.ACTIONS_GITHUB_TOKEN }} - checkName: test - ref: ${{ github.event.pull_request.head.sha || github.sha }} - timeoutSeconds: 1200 - intervalSeconds: 30 - name: automerge uses: pascalgn/automerge-action@v0.13.0 env: From 44efeeca3de4bb1c750927995afe776cfbfafa57 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Thu, 23 Oct 2025 09:59:18 -0400 Subject: [PATCH 04/10] update summary --- .github/MIGRATION_SUMMARY.md | 44 ++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/.github/MIGRATION_SUMMARY.md b/.github/MIGRATION_SUMMARY.md index b7b5eb6a945..26a48a581f4 100644 --- a/.github/MIGRATION_SUMMARY.md +++ b/.github/MIGRATION_SUMMARY.md @@ -28,21 +28,29 @@ This document summarizes the migration from CircleCI to GitHub Actions completed ### 1. `.github/workflows/automerge.yml` -- **Change**: Updated CircleCI check reference from `build-test` to `test` -- **Reason**: The test suite is now run via GitHub Actions workflow named "Test Suite" with job name "test" +- **Changes**: + - Updated CircleCI check reference from `build-test` to `test` + - Removed redundant `wait-for-check` step +- **Reason**: The `pascalgn/automerge-action` automatically waits for all required status checks configured in branch protection rules, making the explicit wait step unnecessary + +### 2. `.github/actions/yarn/action.yml` + +- **Change**: Added `cache: 'yarn'` to `setup-node` action +- **Reason**: Enables automatic caching of Yarn dependencies using GitHub Actions' built-in caching -### 2. `README.md` +### 3. `README.md` - **Changes**: - Replaced CircleCI badge with GitHub Actions badge - Updated publishing documentation to reference GitHub Actions instead of CircleCI -### 3. `nx.json` +### 4. `nx.json` - **Change**: Updated `ci` named input to reference GitHub Actions workflows -- **Before**: Referenced `.circleci/config.yml` and `.github/push.yml` +- **Before**: Referenced `.circleci/config.yml` and `.github/push.yml` (both incorrect/non-existent) - **After**: References `.github/workflows/**/*.yml` and `.github/actions/**/*.yml` - **Impact**: Nx will now properly invalidate caches when any GitHub Actions workflow or action changes +- **Documentation**: [Nx Named Inputs](https://nx.dev/concepts/more-concepts/customizing-inputs#named-inputs) ## Files Deleted @@ -130,12 +138,15 @@ All workflows include comprehensive caching to speed up builds, matching CircleC Before considering this migration complete, verify: +- [ ] Verify required secrets are configured (`ACTIONS_GITHUB_TOKEN`, `NODE_AUTH_TOKEN`) +- [ ] Confirm branch protection rules require: `test`, `format`, `lint (lint)`, `lint (verify)` - [ ] Merge a PR to main and confirm packages are published correctly - [ ] Verify GitHub releases are created with proper changelog - [ ] Confirm Storybook deploys to GitHub Pages successfully -- [ ] Check that automerge still works with the new test check name +- [ ] Check that automerge waits for all required checks before merging - [ ] Verify concurrency controls prevent overlapping publishes/deploys - [ ] Ensure skip-automated-commits properly prevents circular builds +- [ ] Confirm Yarn/Nx/webpack caches are working (check workflow run times) ## Secrets Required @@ -145,12 +156,31 @@ Ensure the following secrets are configured in GitHub: - `NODE_AUTH_TOKEN` - For publishing to npm - Other existing secrets used by other workflows +## Summary of All Changes + +**New files (3):** + +- `.github/workflows/publish-production.yml` - Publishes production packages to npm +- `.github/workflows/deploy-production.yml` - Deploys production Storybook to GitHub Pages +- `.github/MIGRATION_SUMMARY.md` - This documentation file + +**Modified files (4):** + +- `.github/workflows/automerge.yml` - Updated check name and removed redundant wait step +- `.github/actions/yarn/action.yml` - Added Yarn caching via setup-node +- `README.md` - Updated badge and documentation +- `nx.json` - Updated CI input references to GitHub Actions + +**Deleted:** + +- `.circleci/` directory - Entire CircleCI configuration removed + ## Rollback Plan If issues arise, you can temporarily: 1. Restore `.circleci/config.yml` from git history 2. Re-enable CircleCI in the repository settings -3. Update the automerge workflow to reference `build-test` again +3. Disable the new production workflows However, this should only be done as a last resort. Most issues can be fixed by updating the new workflows. From 81ec370f46e07780538f0351c9a592b290da7820 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Thu, 23 Oct 2025 10:47:30 -0400 Subject: [PATCH 05/10] pull --- packages/gamut/src/Badge/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gamut/src/Badge/index.tsx b/packages/gamut/src/Badge/index.tsx index 04bd54a67c7..90450cefad6 100644 --- a/packages/gamut/src/Badge/index.tsx +++ b/packages/gamut/src/Badge/index.tsx @@ -128,5 +128,5 @@ export const Badge: React.FC = ({ icon, children, ...rest }) => { iconPosition: 'left', iconSize, }); - return {content}; + return {content} failure; }; From e8d3517e05435a719f1f56f76002067c96813e0d Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Thu, 23 Oct 2025 12:25:34 -0400 Subject: [PATCH 06/10] test passes --- packages/gamut/src/Badge/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gamut/src/Badge/index.tsx b/packages/gamut/src/Badge/index.tsx index 90450cefad6..04bd54a67c7 100644 --- a/packages/gamut/src/Badge/index.tsx +++ b/packages/gamut/src/Badge/index.tsx @@ -128,5 +128,5 @@ export const Badge: React.FC = ({ icon, children, ...rest }) => { iconPosition: 'left', iconSize, }); - return {content} failure; + return {content}; }; From 72f12445378759d6bad1fe93f57adf9d1ed4b250 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Tue, 28 Oct 2025 14:34:53 -0400 Subject: [PATCH 07/10] jake fix --- .github/workflows/deploy-production.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml index c2fe707f54d..f29202ba893 100644 --- a/.github/workflows/deploy-production.yml +++ b/.github/workflows/deploy-production.yml @@ -6,7 +6,6 @@ on: - main env: - NODE_VERSION: '22.13.1' NODE_OPTIONS: '--max_old_space_size=8196' NX_CLOUD: false IGNORE_COMMIT_MESSAGE: 'chore(release): publish' From 0594990f8e80ea1ef6920b3804ee4fae6f728fcd Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Tue, 28 Oct 2025 15:00:52 -0400 Subject: [PATCH 08/10] finishing touches --- .github/MIGRATION_SUMMARY.md | 186 ----------------------------------- README.md | 2 +- 2 files changed, 1 insertion(+), 187 deletions(-) delete mode 100644 .github/MIGRATION_SUMMARY.md diff --git a/.github/MIGRATION_SUMMARY.md b/.github/MIGRATION_SUMMARY.md deleted file mode 100644 index 26a48a581f4..00000000000 --- a/.github/MIGRATION_SUMMARY.md +++ /dev/null @@ -1,186 +0,0 @@ -# CircleCI to GitHub Actions Migration Summary - -This document summarizes the migration from CircleCI to GitHub Actions completed on October 21, 2025. - -## New GitHub Actions Workflows Created - -### 1. `publish-production.yml` - -- **Purpose**: Publishes production packages to npm when changes are merged to main -- **Trigger**: Push to main branch -- **Key Features**: - - Skips automated release commits to prevent circular builds - - Uses Lerna for conventional commit-based versioning - - Creates GitHub releases automatically - - Uses concurrency control to prevent simultaneous publish jobs - -### 2. `deploy-production.yml` - -- **Purpose**: Deploys production Storybook to GitHub Pages when changes are merged to main -- **Trigger**: Push to main branch -- **Key Features**: - - Builds all packages and Storybook - - Deploys to GitHub Pages using gh-pages - - Uses concurrency control to prevent simultaneous deploy jobs - - Skips automated release commits - -## Files Modified - -### 1. `.github/workflows/automerge.yml` - -- **Changes**: - - Updated CircleCI check reference from `build-test` to `test` - - Removed redundant `wait-for-check` step -- **Reason**: The `pascalgn/automerge-action` automatically waits for all required status checks configured in branch protection rules, making the explicit wait step unnecessary - -### 2. `.github/actions/yarn/action.yml` - -- **Change**: Added `cache: 'yarn'` to `setup-node` action -- **Reason**: Enables automatic caching of Yarn dependencies using GitHub Actions' built-in caching - -### 3. `README.md` - -- **Changes**: - - Replaced CircleCI badge with GitHub Actions badge - - Updated publishing documentation to reference GitHub Actions instead of CircleCI - -### 4. `nx.json` - -- **Change**: Updated `ci` named input to reference GitHub Actions workflows -- **Before**: Referenced `.circleci/config.yml` and `.github/push.yml` (both incorrect/non-existent) -- **After**: References `.github/workflows/**/*.yml` and `.github/actions/**/*.yml` -- **Impact**: Nx will now properly invalidate caches when any GitHub Actions workflow or action changes -- **Documentation**: [Nx Named Inputs](https://nx.dev/concepts/more-concepts/customizing-inputs#named-inputs) - -## Files Deleted - -### 1. `.circleci/` directory - -- **Removed**: Entire CircleCI configuration directory -- **Reason**: All workflows have been successfully migrated to GitHub Actions - -## Workflow Comparison - -| CircleCI Job | GitHub Actions Workflow | Status | -| --------------- | ------------------------------------ | ----------- | -| `checkout_code` | Integrated into individual workflows | ✅ Migrated | -| `publish` | `publish-production.yml` | ✅ Migrated | -| `deploy` | `deploy-production.yml` | ✅ Migrated | - -## Key Design Decisions - -### 1. **DRY Principles** - -All workflows reuse the existing composite actions in `.github/actions/`: - -- `yarn/` - Node.js setup and dependency installation -- `set-git-user/` - Git user configuration -- `set-npm-token/` - NPM authentication -- `skip-automated-commits/` - Skip release commits -- `validate-pr-context/` - Ensure PR context exists - -### 2. **Concurrency Control** - -Replaced CircleCI's queue orb with GitHub Actions concurrency groups: - -- `publish-production` - Ensures only one publish runs at a time -- `deploy-production` - Ensures only one deploy runs at a time -- Both set `cancel-in-progress: false` to avoid canceling active deployments - -### 3. **Consistent Patterns** - -Followed patterns established in existing workflows: - -- Same Node.js version (`22.13.1`) -- Same runner (`ubuntu-22.04`) -- Same environment variables -- Same timeout settings (30 minutes) -- Same permissions structure - -### 4. **Caching Strategy** - -All workflows include comprehensive caching to speed up builds, matching CircleCI's strategy: - -**Yarn dependencies** (via `yarn` action): - -- Cached automatically by `setup-node` action using `cache: 'yarn'` -- Cache key based on `yarn.lock` hash -- Equivalent to CircleCI's yarn cache - -**Nx build cache** (in production workflows): - -- Path: `node_modules/.cache/nx` -- Primary key: `nx-{OS}-{yarn.lock}-{branch}-{run_id}` (similar to CircleCI's epoch-based key) -- Restore keys fall back progressively: branch → yarn.lock → OS -- Uses standard `actions/cache@v4` which automatically saves on success - -**Webpack cache** (in deploy workflow): - -- Paths: `node_modules/.cache` and `packages/styleguide/node_modules/.cache` -- Primary key: `webpack-{OS}-{yarn.lock}-{branch}-{commit_sha}` (matches CircleCI's revision-based key) -- Restore keys fall back to branch and yarn.lock levels -- Only included in deploy workflow since it's specifically needed for Storybook builds - -**Key improvements over CircleCI:** - -- Uses GitHub Actions' native `actions/cache@v4` (simpler than separate restore/save) -- Automatic cache saving (no need for `if: always()` conditions) -- `github.run_id` for Nx provides unique per-run keys similar to CircleCI's `{{ epoch }}` -- `github.sha` for webpack matches CircleCI's `{{ .Revision }}` - -### 5. **Security Best Practices** - -- Minimal permissions using principle of least privilege -- Separate tokens for different purposes (`ACTIONS_GITHUB_TOKEN` vs `NODE_AUTH_TOKEN`) -- Explicit permission declarations for each workflow - -## Testing Checklist - -Before considering this migration complete, verify: - -- [ ] Verify required secrets are configured (`ACTIONS_GITHUB_TOKEN`, `NODE_AUTH_TOKEN`) -- [ ] Confirm branch protection rules require: `test`, `format`, `lint (lint)`, `lint (verify)` -- [ ] Merge a PR to main and confirm packages are published correctly -- [ ] Verify GitHub releases are created with proper changelog -- [ ] Confirm Storybook deploys to GitHub Pages successfully -- [ ] Check that automerge waits for all required checks before merging -- [ ] Verify concurrency controls prevent overlapping publishes/deploys -- [ ] Ensure skip-automated-commits properly prevents circular builds -- [ ] Confirm Yarn/Nx/webpack caches are working (check workflow run times) - -## Secrets Required - -Ensure the following secrets are configured in GitHub: - -- `ACTIONS_GITHUB_TOKEN` - For creating releases and pushing to gh-pages -- `NODE_AUTH_TOKEN` - For publishing to npm -- Other existing secrets used by other workflows - -## Summary of All Changes - -**New files (3):** - -- `.github/workflows/publish-production.yml` - Publishes production packages to npm -- `.github/workflows/deploy-production.yml` - Deploys production Storybook to GitHub Pages -- `.github/MIGRATION_SUMMARY.md` - This documentation file - -**Modified files (4):** - -- `.github/workflows/automerge.yml` - Updated check name and removed redundant wait step -- `.github/actions/yarn/action.yml` - Added Yarn caching via setup-node -- `README.md` - Updated badge and documentation -- `nx.json` - Updated CI input references to GitHub Actions - -**Deleted:** - -- `.circleci/` directory - Entire CircleCI configuration removed - -## Rollback Plan - -If issues arise, you can temporarily: - -1. Restore `.circleci/config.yml` from git history -2. Re-enable CircleCI in the repository settings -3. Disable the new production workflows - -However, this should only be done as a last resort. Most issues can be fixed by updating the new workflows. diff --git a/README.md b/README.md index 0d9999af725..961f3b0473e 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Every PR that changes files in a package publishes alpha releases that you can u > NOTE: in case an alpha build is not published upon opening of the PR or Draft PR, re-run the `build-test` check and that will re-run the alpha build publishing flows 1. Create a PR or Draft PR. - - This will kickoff a Circle-CI workflow which will publish an alpha build. (This will appear in Github as the "Deploy") + - This will kickoff a Github Action workflow which will publish an alpha build. (This will appear in Github as the "Deploy") 1. After the alpha build is published, the `codecademydev` bot should comment on your PR with the names of the published alpha packages.
1. Install this version of the package in your application you wish to test your changes on. From 653bb46aed08a2ec7017ca4c970bb25012dca8fe Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Wed, 29 Oct 2025 09:40:59 -0400 Subject: [PATCH 09/10] capitalize Badge comment --- packages/gamut/src/Badge/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gamut/src/Badge/index.tsx b/packages/gamut/src/Badge/index.tsx index 04bd54a67c7..4d95dd95412 100644 --- a/packages/gamut/src/Badge/index.tsx +++ b/packages/gamut/src/Badge/index.tsx @@ -65,7 +65,7 @@ const sizeVariants = variant({ }, sm: { height: `1rem`, - // the powers that be told us this was okay. please don't do this. seriously. - <3 web-plat + // The powers that be told us this was okay. Please don't do this. Seriously. - <3 Web-Plat fontSize: 10 as any, }, }, From dd7207a3e253069c57c02d9fbf41378725976604 Mon Sep 17 00:00:00 2001 From: dreamwasp Date: Wed, 29 Oct 2025 09:46:29 -0400 Subject: [PATCH 10/10] fixed --- packages/styleguide/src/lib/Meta/Best Practices.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/styleguide/src/lib/Meta/Best Practices.mdx b/packages/styleguide/src/lib/Meta/Best Practices.mdx index 733ccd47ebb..01fba299992 100644 --- a/packages/styleguide/src/lib/Meta/Best Practices.mdx +++ b/packages/styleguide/src/lib/Meta/Best Practices.mdx @@ -228,11 +228,13 @@ const Content = ({ children }) => ( # ❌ Nested selectors -Nested selectors can cause a huge amount of side effects unwittingly and make it very hard to maintain consistent behavior while making updates. We politely ask (and will shortly lint) that you refrain from using: +Nested selectors can cause a huge amount of side effects unwittingly and make it very hard to maintain consistent behavior while making updates. We politely ask that you refrain from using: - **Tag Selectors** - `*` `div` `p` `span` - **Component Selectors (From Gamut)** - EG: `Box` +You may still do so, but at your own risk. Please consider alternatives such as using system props, utility functions from `gamut-styles`, or wrapping components in layout components such as `FlexBox` or `GridBox`. + ```tsx //❌ Don't do this❌ const App = styled.main`