google / google/clasp

[RFC] (Re)create consistent GAS project for codebase: `remote create` (multi-developer workflow)

Open
#991 0 comments 2 reactions 0 assignees View on GitHub
feature request
Dominant language
TypeScript
Stars
5.8k
Forks
510
Avg merge
5h 27m
Merged PRs (30d)
1

Description

Depends on #989. For simplicity this proposal assumes it has been implemented.

> To prevent ambiguity the term "project" in this proposal always refers to a Google Apps Script (GAS) project and "codebase" is used for a local project code folder/repository.

In most multi-developer workflows each developer has their own personal testing environment based on a shared codebase structure.
Unfortunately such a multi-developer workflow is currently not well-supported by clasp, as demonstrated by the discussion in #921.

Private remotes as proposed in #989 would solve a significant portion of the hassle, but the resulting workflow still has a couple of flaws and limitations:

- `create` implicitly drags some default files into the codebase (#758).
- `create` with `git clone` (#758) is unnatural when the codebase is already on your machine.
- Some information for `create` such as `--title` and `--type` are not stored anywhere, so they can't be shared and tracked by version control to create consistent testing environments.
- A combination of `create`, `remote add`, `push` and some juggling with files _works_, but is unnecessarily complicated and prone to mistakes.

The running theme here is that there's no easy way to reliably and consistently (re)create a GAS project based on the shared structure of a codebase, similar to something like Docker or "Infrastructure as Code".

You could turn to scripting, but that's a treacherous path of system differences and shoddy error handling.
This workflow is so common that I strongly believe it deserves first-party support. Scripting should only be necessary for truly custom scenarios.

### Usecases
- Multi-developer workflow (#921).
- Push existing codebase to GAS (#758).
- clasp's own testing infrastructure (#987).
- Ephemeral GAS projects for CI testing.
- (Automated) PR staging.

### Prior art
- [`gcloud deployment-manager deployments create`](https://cloud.google.com/sdk/gcloud/reference/deployment-manager/deployments/create).
- [`terraform apply`](https://developer.hashicorp.com/terraform/cli/commands/apply).
- [`docker compose up`](https://docs.docker.com/engine/reference/commandline/compose_up/).
- Note that #989 already covers [`compose down`](https://docs.docker.com/engine/reference/commandline/compose_down/) with `remote remove --delete`.
- [`gh codespace create`](https://cli.github.com/manual/gh_codespace_create).

### Configuration
To consistently (re)create GAS projects some extra information needs to be added to `.clasp.json`:
- `type`: store after `create`/`clone`.
- `title`:
- Ask during `create` if not specified, suggest `name` of `package.json` or the name of the directory of `.clasp.json`.
- Use title of cloned project during `clone`.

### New subcommand: `remote create`
The existing `create` command is intended to create a _new_ codebase with accompanying GAS project, like you would do on [scripts.google.com](https://script.google.com/).
We need a command that creates only a GAS project based on an _existing_ codebase. I propose the following new subcommand:

```
clasp remote create
```

This command should handle this workflow in three steps:

1. Add a new remote called `` to the codebase (private by default).
2. Create a new (empty) GAS project based on `.clasp.json`.
3. Push the codebase to this new remote.

#### Options
- All options for `remote add` should be propagated, except:
- `` (newly created)
- `--pull` (can't pull from a new project)
- All options for `create` should be propagated, except:
- `--remote-name` (covered by ``)
- `--remote-default` (covered by `remote add`'s `--default`)
- `--type` (read from `.clasp.json`)
- `--rootDir` (using existing codebase)
- `--recycle` or `-r` to reuse an existing GAS project with the same title
- `--title-suffix` to add to the base `title`, e.g. "MyScript-dev". Defaults to the provided remote ``, or an empty string if `--title` is explicitly specified.

#### Implementation notes
- The `title` in `.clasp.json` can be overidden with `--title(-suffix)`, this is not important for the consistency of the testing environment.
- If `--title` is not explicitly specified the base title of the new GAS project should default to:
1. `title` in `.clasp.json`.
2. `name` in `package.json`.
3. The `dirname` of the folder that contains `.clasp.json`.
- If `--title-suffix` is set to an empty string no dash should be added.
- Error if a GAS project with the resolved full title already exists, unless `--recycle` is specified. This avoids accidental data loss.
- `--recycle` should adjust the existing GAS project to the structure defined in `.clasp.json`, but preserve existing versions and deployments.
- If `--parentId` is specified check if the inferred `--type` matches `.clasp.json`.

`remote create` felt more natural than `create --empty` as proposed in #758, since it explicitly signals creating only a new _remote_ rather than a whole new _codebase_. Having `create` behave significantly differently in a folder with a `.clasp.json` seems undesirable and would probably be a breaking change.

### Other considerations
1. Is sharing a codebase across projects with varying `type`-s a thing? If so, `type` could be moved/added to the `remotes` object with some form of shared default setting.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.