npm package: @svartkonst/tag
Description: A simple library for creating tags/constructors - Annotated data types that are ergonomic to use and work well with the TypeScript type system.
Author: Emil Johnsen
Latest version: 0.0.0

# TypeScript Library Starter

A starter project, with installer, that configures a basic TypeScript project complete with:

* NPM scripts to manage committing, testing, publishing, versioning, and more.
* Config files for ESLint, Jest, and TypeScript
* Commitizen, to homogenize commit messages
* Git repo initialization

## Installation & setup

Before installation, you probably need to have a global Git user configured. In order to automatically set up a remote, you might need SSH access to Bitbucket. I don't know.

### 1. Create a project folder
```
$ mkdir interesting-thing
$ cd interesting-thing
```
### 2. Clone this project
```
git clone git@bitbucket:diseinc/typescript-library-starter.git . # note the "."
```

### 3. Run `npm install`
### 4. Complete the interactive setup
After all the dependencies are installed, an interactive prompt will start. When all the questions have been answered, actual setup begins.

* _Name, version, description, author, types_ and _license_ are written as-is to their corresponding fields in `package.json`, similar to running `npm init`.
* _Entry point_ is written as-is to the package.json _main_ field. _Entry point_ and _types_ should both point to `./lib`.
* If _Auto-set repository?_ is true, then the _repository_ field is inferred from project name. If it's false, you will be prompted for a repository URL.
* Likewise, if _Auto-set Git remote?_ then it will infer a URL from the project name, and run `git remote add origin <url>`
* If _Add Bitbucket Pipelines?_ is true, then a config file will be created.

When all queries are answered, the installer will:
* Replace `package.json`. `package-lock.json` is removed entirely.
* Move all config files from `./template/*` to root-
* Remove the existing Git repo, initialize a new one, and commit all files as "initial commit".
* Add a Git remote called `origin`, if _Auto-set Git remote?_ is true
* Install and setup Commitizen
* Remove `install.js`
* Urge you to run `npm install`. You should do this in order to install the new project dependencies, as well as clear out the old ones.

Your repo is now good to go.

## Usage

After running `npm install`, you're free to tweak the settings and begin developing your project. To help with that, this repository is equipped with a few tools.

### Linting
Linting is done with ESLint, configured for TypeScript according to the TSLint migration guide. It's currently setup with the recommended rules only.

Use `npm run lint` to lint all files, and `npm run lint:fix` to automatically fix violations.

### Testing
Testing is done via Jest, using `ts-jest` to transform files. It's set up with a very basic configuration.

Use `npm test` to run all tests + code coverage, or `npm test:watch` to run the test suites only, in watch mode.

### Commits
Committing code changes is done via Commitizen, in order to standardize and improve commit messages where possible. Commit message should follow the [Angular guidelines](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines).

Use `npm run commit`.

### Versioning and publishing
Use the built-in commands `npm version` and `npm publish --access=public` to bump project version and/or publish the library.

NPM script hooks are provided in order to lint, test, and build code before the version is bumped, and before the package is published. A `postversion` tags the version, and pushes it to remote.

### If your project isn't a published library
This starter project was initially created with libraries in mind, i.e. projects that end up versioned and published to NPM.

Not all projects are made equal, however, and if your project isn't a library in that sense, you may disregard/remove the `prepublishOnly` NPM script, and possibly `version`.

## Set up your Bitbucket repository
Unfortunately, this starter can't do everything for you. In addition to a properly set up project folder, you should also have a properly set up Bitbucket repository.

The exact nature of your settings depend slightly on team size and project goals, but our recommendations are as follows:

* Go to ⚙️**Settings > Repository details** and set "Landing page" to "Pull Requests".  
This is, by far, where we spend most of our time  in the repo, and shaving a few mouse clicks, and a few seconds of load time, is wonderful.
* "Main branch" should be set to `master` by default.
* Go to ⚙️**Settings > Branch permissions**  
  * `master` should have:
    * "Write access" set to "none"
    * "Merge via pull request" set to "Everybody".
    * "☑️ Check for unresolved pull request tasks"
    * "☑️ Check the last commit for at least 1 successful build and no failed build"
  * `develop` should have the same setup as `master`, but add:
      * "☑️ Check for at least 2 approvals".  
        * _You could also use "from default reviewers", or a combination. The purpose is part code quality, but mostly to share knowledge about your work._
* Go to ⚙️**Settings > Branching model**
  * Set "Development branch" to `develop` and "Production branch" to `master`.
  * Tick all the boxes. Maybe not "Release". Who cares about that one.
* Go to ⚙️**Settings > Merge strategies** and set "Default merge strategy" to "Merge commit".  
  * _Historically, we've preferred to use "Squash" for PRs moving into `develop`, and "merge commit" for PRs moving into `master`._  
  * _Since accidentally leaving it on "Squash" when merging `develop -> master` is terribly catastrophic, but leaving it on "Merge commit" just makes your history ugly, we prefer to use "Merge" as a default._  
  * _Ideally, all commits are rebased and prettified before merging anyway, but..._  
  * _Also, usage of Commitizen might mitigate some/all of those issues. Or make them worse._
  * _Really, they should probably be set to FF only, and all branches rebased. Well._
* Go to ⚙️**Settings > Default reviewers** and add some. It'll make your life easier.
* You should set up **Bitbucket pipelines** to run lint, test, and build on all commits in a pull request, to prevent merging broken commits. See `template/bitbucket-pipelines.yml` for a basic example.
* You _could_ go to ⚙️**Settings > Default description** and add a default PR description. When we tried it out, it didn't work as well as we wanted. Looks promising now, though, so try it out. There's a default template in the wiki. Somewhere.
* Those are all the settings we use so far. You should probably set up Deployments or CI integrations or something, too.