For now, only one `pyodide` can be loaded in a given global scope because we need to use a global variable for package loading. This changes `loadPyodide` so that it no longer defines `globalThis.pyodide` in favor of just returning `pyodide` from `loadPyodide`. `Module` is placed on the global object as `globalThis.__pyodide_module` for the purposes of package loading. I added documentation to explicitly state that `loadPyodide` can only be run once in each global Javascript context, an error will be thrown otherwise.

This has two advantages: 
1. The returned `pyodide` module is understandable to Typescript and other code analysis, whereas the global variable is not understandable.
2. If in the future we are able to remove the global variable, no further API change will be needed (other than relaxing the documented "pyodide must be globally-unique" constraint). I figure it's better to make this API change earlier rather than later.

It will be possible to completely remove the global variable dependence when Firefox implements support for using ES6 modules in webworkers (see https://bugzilla.mozilla.org/show_bug.cgi?id=1247687).
API Don't expose pyodide as a global variable in loadPyodide. For now, only one `pyodide` can be loaded in a given global scope because we need to use a global variable for package loading. This changes `loadPyodide` so that it no longer defines `globalThis.pyodide` in favor of just returning `pyodide` from `loadPyodide`. `Module` is placed on the global object as `globalThis.__pyodide_module` for the purposes of package loading. I added documentation to explicitly state that `loadPyodide` can only be run once in each global Javascript context, an error will be thrown otherwise.

This has two advantages: 
1. The returned `pyodide` module is understandable to Typescript and other code analysis, whereas the global variable is not understandable.
2. If in the future we are able to remove the global variable, no further API change will be needed (other than relaxing the documented "pyodide must be globally-unique" constraint). I figure it's better to make this API change earlier rather than later.

It will be possible to completely remove the global variable dependence when Firefox implements support for using ES6 modules in webworkers (see https://bugzilla.mozilla.org/show_bug.cgi?id=1247687).
(maintainer-information)=
# Maintainer information

## Making a release

For branch organization we use a variation of the [Github
Flow](https://guides.github.com/introduction/flow/) with
the latest release branch named `stable` (due to ReadTheDocs constraints).

(making-major-release)=
### Making a major release

1. Make a new PR and for all occurrences of
   `https://cdn.jsdelivr.net/pyodide/dev/full/` in `./docs/` replace `dev` with
   the release version `vX.Y.Z` (note the presence of the leading `v`). This
   also applies to `docs/conf.py`
2. Set version in `src/py/pyodide/__init__.py`
3. Make sure the change log is up to date.
    - Indicate the release date in the change log.
    - Generate the list of contributors for the release at the end of the
      changelog entry with,
      ```bash
      git shortlog -s LAST_TAG.. | cut -f2- | sort --ignore-case | tr '\n' ';' | sed 's/;/, /g;s/, $//' | fold -s
      ```
      where `LAST_TAG` is the tag for the last release.
   Merge the PR.
4. Assuming the upstream `stable` branch exists, rename it to a release branch
   for the previous major version. For instance if last release was, `0.20.0`,
   the corresponding release branch would be `0.20.X`,
   ```bash
   git fetch upstream
   git checkout stable
   git checkout -b 0.20.X
   git push upstream 0.20.X
   git branch -D stable    # delete locally
   ```
5. Create a tag `X.Y.Z` (without leading `v`) and push
   it to upstream,
   ```bash
   git tag X.Y.Z
   git push upstream X.Y.Z
   ```
   Create a new `stable` branch from this tag,
   ```bash
   git checkout -b stable
   git push upstream stable --force
   ```
   Wait for the CI to pass and create the release on GitHub.
6. Build the pre-built Docker image locally and push,
   ```bash
   docker build -t pyodide/pyodide:X.Y.Z -f Dockerfile-prebuilt --build-arg VERSION=BB .
   docker push
   ```
   where `BB` is the last version of the `pyodide-env` Docker image.
7. Revert Step 1. and increment the version in
   `src/py/pyodide/__init__.py` to the next version specified by
   Semantic Versioning.

### Making a minor release

For a minor release, commits need to be added to the `stable` branch, ideally via a PR.
This can be done with either,
 - git cherry picking individual commits,
   ```bash
   git checkout stable
   git pull
   git checkout -b backport-branch
   git cherry-pick <commit-hash>
   ```
 - or with interactive rebase,
   ```bash
   git fetch upstream
   git checkout stable
   git pull
   git checkout -b backport-branch
   git rebase -i upstream/main
   ```
   and indicate which commits to take from `main` in the UI.


Then follow steps 2, 3, and 6 from {ref}`making-major-release`.

### Fixing documentation for a released version

Cherry pick the corresponding documentation commits to the `stable` branch. Use
`[skip ci]` in the commit message.

(maintainer-information)=
# Maintainer information

## Making a release

For branch organization we use a variation of the [Github
Flow](https://guides.github.com/introduction/flow/) with
the latest release branch named `stable` (due to ReadTheDocs constraints).

(making-major-release)=
### Making a major release

1. Make a new PR and for all occurrences of
   `https://cdn.jsdelivr.net/pyodide/dev/full/` in `./docs/` replace `dev` with
   the release version `vX.Y.Z` (note the presence of the leading `v`). This
   also applies to `docs/conf.py`
2. Set version in `src/py/pyodide/__init__.py`
3. Make sure the change log is up to date.
    - Indicate the release date in the change log.
    - Generate the list of contributors for the release at the end of the
      changelog entry with,
      ```bash
      git shortlog -s LAST_TAG.. | cut -f2- | sort --ignore-case | tr '\n' ';' | sed 's/;/, /g;s/, $//' | fold -s
      ```
      where `LAST_TAG` is the tag for the last release.
   Merge the PR.
4. Assuming the upstream `stable` branch exists, rename it to a release branch
   for the previous major version. For instance if last release was, `0.20.0`,
   the corresponding release branch would be `0.20.X`,
   ```bash
   git fetch upstream
   git checkout stable
   git checkout -b 0.20.X
   git push upstream 0.20.X
   git branch -D stable    # delete locally
   ```
5. Create a tag `X.Y.Z` (without leading `v`) and push
   it to upstream,
   ```bash
   git tag X.Y.Z
   git push upstream X.Y.Z
   ```
   Create a new `stable` branch from this tag,
   ```bash
   git checkout -b stable
   git push upstream stable --force
   ```
   Wait for the CI to pass and create the release on GitHub.
6. Build the pre-built Docker image locally and push,
   ```bash
   docker build -t pyodide/pyodide:X.Y.Z -f Dockerfile-prebuilt --build-arg VERSION=BB .
   docker push
   ```
   where `BB` is the last version of the `pyodide-env` Docker image.
7. Revert Step 1. and increment the version in
   `src/py/pyodide/__init__.py` to the next version specified by
   Semantic Versioning.

### Making a minor release

For a minor release, commits need to be added to the `stable` branch, ideally via a PR.
This can be done with either,
 - git cherry picking individual commits,
   ```bash
   git checkout stable
   git pull
   git checkout -b backport-branch
   git cherry-pick <commit-hash>
   ```
 - or with interactive rebase,
   ```bash
   git fetch upstream
   git checkout stable
   git pull
   git checkout -b backport-branch
   git rebase -i upstream/main
   ```
   and indicate which commits to take from `main` in the UI.


Then follow steps 2, 3, and 6 from {ref}`making-major-release`.

### Fixing documentation for a released version

Cherry pick the corresponding documentation commits to the `stable` branch. Use
`[skip ci]` in the commit message.
