Setup
Script Recipe
nvm install 20.12.2
nvm use 20.12.2
npx create-nx-workspace@19.8.14 buildmotion-github-motion --verbose
cd buildmotion-github-motion
rm package-lock.json
echo "v20.12.2" > .nvmrc
yarn add @nx/plugin@19.8.14 -D -W
# Create a new GitHub repository; private; no README; no .gitignore; no license
git init
git config --global init.defaultBranch main
git branch -m main
git add .
git commit -am "chore(workspace): initial commit"
git remote add origin https://github.com/buildmotion/github-motion.git
git remote -v
git push -u origin main
yarn add husky @commitlint/cli @commitlint/config-conventional -D -W
yarn husky init
echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg
cat << 'EOF' > commitlint.config.js
// Create commitlint.config.js at the root:
// Note: We can customize the rules based on our .
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
[
'feat', // Features
'fix', // Bug fixes
'docs', // Documentation changes
'style', // Code style (formatting)
'refactor', // Refactoring
'test', // Adding or updating tests
'chore', // Other changes (e.g., deps, build)
'ci', // CI/CD changes
'perf' // Performance improvements
]
],
'subject-case': [2, 'always', 'lowercase'], // Ensure proper capitalization
'header-max-length': [2, 'always', 140] // Max header length
}
};
EOF
echo "# yarn test" > .husky/pre-commit
git add .
git status
git commit -am "chore(workspace): add commitlint configuration with husky"
git push
code .
Notes:
- create a generator to add the conventional commit configuration
- create generator to add Nx Release configuration for workspace and projects
Nx Workspace
An Nx workspace is a collection of projects and libraries that share dependencies and build tools. It is an extensible dev environment that provides a powerful CLI to create, develop, build, test, and deploy your code. The following options are available when creating an Nx workspace:
| Option | Description | Type | Default | Choices |
|---|---|---|---|---|
| --help | Show help | boolean | ||
| --version | Show version | boolean | ||
| --name | Workspace name (e.g. org name) | string | ||
| --preset | Customizes the initial content of your workspace | string | ["apps", "npm", "ts", "web-components", "angular-monorepo", "angular-standalone", "react-monorepo", "react-standalone", "vue-monorepo", "vue-standalone", "nuxt", "nuxt-standalone", "next", "nextjs-standalone", "remix-monorepo", "remix-standalone", "react-native", "expo", "nest", "express", "react", "vue", "angular", "node-standalone", "node-monorepo", "ts-standalone"] | |
| --interactive | Enable interactive mode with presets | boolean | true | |
| --workspaceType | The type of workspace to create | string | ["integrated", "package-based", "standalone"] | |
| --appName | The name of the app when using a monorepo with certain stacks | string | ||
| --style | Stylesheet type to be used with certain stacks | string | ||
| --standaloneApi | Use Standalone Components if generating an Angular app | boolean | true | |
| --routing | Add a routing setup for an Angular app | boolean | true | |
| --bundler | Bundler to be used to build the app | string | ||
| --workspaces | Use package manager workspaces | boolean | false | |
| --formatter | Code formatter to use | string | ||
| --framework | Framework option to be used with certain stacks | string | ||
| --docker | Generate a Dockerfile for the Node API | boolean | ||
| --nextAppDir | Enable the App Router for Next.js | boolean | ||
| --nextSrcDir | Generate a 'src/' directory for Next.js | boolean | ||
| --e2eTestRunner | Test runner to use for end to end (E2E) tests | string | ["playwright", "cypress", "none"] | |
| --ssr | Enable Server-Side Rendering (SSR) and Static Site Generation (SSG/Prerendering) for the Angular application | boolean | ||
| --prefix | Prefix to use for Angular component and directive selectors | string | ||
| --defaultBase | Default base to use for new projects | string | main | |
| -g, --skipGit | Skip initializing a git repository | boolean | false | |
| --commit.name | Name of the committer | string | ||
| --commit.email | E-mail of the committer | string | ||
| --commit.message | Commit message | string | "Initial commit" | |
| --packageManager, --pm | Package manager to use | string | npm | ["bun", "npm", "pnpm", "yarn"] |
| -a, --allPrompts | Show all prompts | boolean | false | |
| --useGitHub | Will you be using GitHub as your git hosting provider? | boolean | false | |
| --nxCloud, --ci | Which CI provider would you like to use? | string | ["github", "gitlab", "azure", "bitbucket-pipelines", "circleci", "skip", "yes"] |
npx create-nx-workspace@19.8.14
Output
npx create-nx-workspace@19.8.14
NX Let's create a new workspace [https://nx.dev/getting-started/intro]
✔ Where would you like to create your workspace? · buildmotion-github-motion
✔ Which stack do you want to use? · none
✔ Package-based monorepo, integrated monorepo, or standalone project? · package-based
✔ Which CI provider would you like to use? · github
NX Creating your v19.8.14 workspace.
✔ Installing dependencies with npm
✔ Successfully created the workspace: buildmotion-github-motion.
✔ Nx Cloud has been set up successfully
✔ CI workflow has been generated successfully
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
NX Nx CLI is not installed globally.
This means that you will have to use "npx nx" to execute commands in the workspace.
Run "npm i -g nx" to be able to execute command directly.
NX Your CI setup is almost complete.
Finish it by visiting: https://cloud.nx.app/connect/CWzlH5sXhp
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
NX First time using Nx? Check out this interactive Nx tutorial.
https://nx.dev/getting-started/tutorials/npm-workspaces-tutorial
Initialize a Git repository
git remote add origin https://github.com/buildmotion/github-motion.git
git branch -M main
git push -u origin main
1. Initialize a Git repository in your Nx workspace (if not already initialized):
git init
git config --global init.defaultBranch main
git branch -m main
- This command initializes a new Git repository in your existing Nx workspace directory. If you’ve already initialized a repo, you can skip this step.
2. Add all workspace files to the staging area:
git add .
- This command stages all changes in the current directory for committing, effectively marking them for inclusion in the next commit.
3. Commit the staged files to your local repository:
git commit -am "chore(workspace): initial commit"
- This creates a new commit with the changes you’ve staged, giving it a descriptive message, in this case, "Initial commit."
4. Add the new GitHub repository as a remote:
git remote add origin https://github.com/buildmotion/github-motion.git
- This command adds a remote repository (hosted on GitHub in this case) with the name
origin. It's essentially a pointer to the remote location where your code will be pushed.
5. Push your local commits to the GitHub repository
git push -u origin main
- This command pushes your local commits to the
masterbranch of the remote repository namedorigin. The-uflag sets the remotemasterbranch as the upstream reference for your local branch, which simplifies future pushes.
Note: If your default branch is main instead of master, use main in step 5:
git push -u origin main
Synchronize Local and Remote Repositories
The error message indicates that the remote GitHub repository has commits that are not present in your local repository. This typically happens if there's an initial commit in the GitHub repo (e.g., a README file) that your local repository doesn't have. To resolve this, you need to synchronize your local repository with the remote repository by pulling the changes before you can push your local commits.
Here’s how to resolve this:
-
Pull the changes from the remote repository:
git pull origin main --allow-unrelated-histories- This command pulls the latest changes from the
mainbranch of the remote repo and attempts to merge them with your local branch. The--allow-unrelated-historiesflag is necessary because your local branch and the remote branch initially have different histories.
- This command pulls the latest changes from the
-
Resolve any merge conflicts, if they occur:
-
If there are any merge conflicts, you’ll need to resolve them manually. Open the files with conflicts, make the necessary changes, stage the changes, and commit them:
git add <file-to-resolve>
git commit -m "Resolve merge conflicts"
-
-
Push your changes after resolving conflicts:
git push -u origin main- This command pushes the committed changes to the
mainbranch of your remote repository.
- This command pushes the committed changes to the
This sequence of commands should synchronize your local workspace with your GitHub repository. Make sure to replace main with the appropriate branch name if your project setup uses a different branch as the default.
How to Handle Divergent Branches
When you see the message "fatal: refusing to merge unrelated histories," it means that Git is refusing to merge branches that have diverged and don't share a common history. This can happen when you're trying to pull changes from a remote branch that has no common ancestor with your local branch.
This message is informing you that your local and remote branches have diverged, and you need to specify how to handle the differences. You have a few options:
-
Merge (default behavior): This is typically used if you want to create a merge commit.
git pull origin main --allow-unrelated-histories --no-rebase- This keeps all history and creates a merge commit.
-
Rebase: This rewrites commit history by applying your changes on top of the fetched branch. This can create a cleaner history.
git pull origin main --allow-unrelated-histories --rebase -
Fast-Forward Only: This approach allows pulling only if the remote branch is a direct descendant of the local branch.
git pull origin main --allow-unrelated-histories --ff-only- This performs the update only if it can be done with a fast-forward. If the branches have diverged, it will abort the operation.
Choose the approach that best fits your use case:
- Use a merge if you want to preserve the diverging history and don’t mind having a merge commit.
- Use rebase if you prefer a cleaner, linear history.
- Use
--ff-onlyif you want to ensure clean histories at the cost of aborting the operation in case of divergence.
Once you've decided on an approach and run the appropriate command, resolve any conflicts if necessary and commit them. Then, push your changes with:
git push -u origin main
This will synchronize your local repository with the remote repository on GitHub.