Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ Please see the fragment files in the `changelog.d directory`_.

.. scriv-insert-here

.. _changelog-1.0.1:

1.0.1 - 2026-06-08
==================

Development
-----------

* Internal robustness improvements.

.. _changelog-1.0.0:

1.0.0 - 2026-06-01
Expand Down
60 changes: 60 additions & 0 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Releasing new versions

Follow this process to release new versions of the GRA CLI.

> [!NOTE]
>
> This process depends on the following tools:
>
> * bash
> * git
> * GitHub CLI
> * just
> * pandoc
> * Poetry
> * twine


## STEP 1: Prep the release branch

Choose a new version number and run this command,
substituting the version number for the word "VERSION".

```shell
just r1-prep-release "VERSION"
```


## STEP 2: Review the CHANGELOG

Review the CHANGELOG for readability, flow, and consistency.
If changes are made, use this command to commit the changes:

```shell
just r2-amend-changelog
```


## STEP 3: Create the release PR

```shell
just r3-create-pr
```

Wait for the release PR to merge.


## STEP 4: Publish

After the release PR merges, run this command:

```shell
just r4-publish
```


## STEP 5: Merge back to main

```shell
just r5-merge-back
```
53 changes: 53 additions & 0 deletions assets/releasing/r1-prep-release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env bash

set -e

require_exit='0'

required_commands=(
gh
pandoc
poetry
scriv
)

for required_command in "${required_commands[@]}"; do
if ! command -v "${required_command}" 1>/dev/null 2>/dev/null; then
echo "${required_command} must be installed."
require_exit='1'
fi
done

# Require that `main` is already checked out.
current_branch="$(git rev-parse --abbrev-ref HEAD)"
if [ "${current_branch}" != 'main' ]; then
echo "You must be on the 'main' branch."
require_exit='1'
fi

# Require a single argument, representing the new version.
if [ "$1" == '' ]; then
echo
echo "USAGE: $0 {VERSION}"
require_exit='1'
fi

if [ "${require_exit}" -eq '1' ]; then
exit 1
fi

# Set the new version.
export VERSION="$1"
export BRANCH="release/${VERSION}"

# Pull the latest changes.
git pull

# Bump the metadata.
git checkout -b "release/${VERSION}"
poetry version "${VERSION}"
scriv collect

# Commit the changes
git add changelog.d/ CHANGELOG.rst pyproject.toml
git commit -m 'Update project metadata'
7 changes: 7 additions & 0 deletions assets/releasing/r2-amend-changelog.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

set -e

# Amend the CHANGELOG.
git add CHANGELOG.rst
git commit --amend -m 'Update project metadata'
33 changes: 33 additions & 0 deletions assets/releasing/r3-create-pr.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env bash

set -e

export VERSION="$(poetry version --short)"
export BRANCH="release/${VERSION}"

# Require that `release/$VERSION` branch is already checked out.
current_branch="$(git rev-parse --abbrev-ref HEAD)"
if [ "${current_branch}" != "${BRANCH}" ]; then
echo "You must be on the '${BRANCH}' branch."
exit 1
fi

# Generate the CHANGELOG fragment.
export CHANGELOG_FRAGMENT="$(mktemp --suffix '.md')"

echo '
> [!NOTE]
>
> Merge with the "Create a merge commit" strategy!
' > "${CHANGELOG_FRAGMENT}"

scriv print --version "${VERSION}" \
| pandoc --from rst --to gfm --wrap preserve --shift-heading-level-by 1 \
>> "${CHANGELOG_FRAGMENT}"

# Create the PR.
git push origin --set-upstream "${BRANCH}"
gh pr create \
--title "Release ${VERSION}" \
--body-file "${CHANGELOG_FRAGMENT}" \
--base 'releases'
29 changes: 29 additions & 0 deletions assets/releasing/r4-publish.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bash

set -e

# Check out the 'releases' branch.
git checkout releases
git pull

export VERSION="$(poetry version --short)"

# Generate the CHANGELOG fragment.
export CHANGELOG_FRAGMENT="$(mktemp --suffix '.md')"
scriv print --version "${VERSION}" \
| pandoc --from rst --to gfm --wrap preserve --shift-heading-level-by 1 \
> "${CHANGELOG_FRAGMENT}"

# Publish the git artifacts.
git tag "v${VERSION}" --annotate --file="${CHANGELOG_FRAGMENT}"
git push --tags # This line triggers a CI job that publishes to PyPI.
gh release create "v${VERSION}" \
--target 'releases' \
--title "${VERSION}" \
--notes-from-tag

# Publish the PyPI artifacts.
rm -rf dist/
poetry build --no-plugins
twine check --strict dist/*
twine upload dist/*
23 changes: 23 additions & 0 deletions assets/releasing/r5-merge-back.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash

set -e

# Push a new branch to the repo.
# If merge conflicts exist, the 'merge-back' branch is where the conflicts can be resolved.
git fetch origin
git push origin refs/remotes/origin/releases:refs/heads/merge-back

# Create the merge-back PR.
export PR_BODY="$(mktemp --suffix '.md')"
echo '
> [!NOTE]
>
> Merge with the "Create a merge commit" strategy!
' > "${PR_BODY}"
gh pr create \
--title 'Merge back to main' \
--body-file "${PR_BODY}" \
--base 'main' \
--head 'merge-back' \
--assignee '@me' \
--label 'no-news-is-good-news'
20 changes: 20 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,23 @@ clean:
rm -rf build
rm -f .coverage.*
find . \( -type d -name __pycache__ -or -name \*.py[oc] \) -delete

# RELEASING 1: Create a new branch and update the project metadata.
r1-prep-release version:
bash assets/releasing/r1-prep-release.sh "{{version}}"

# RELEASING 2: (OPTIONAL) Amend the CHANGELOG after changes are made.
r2-amend-changelog:
bash assets/releasing/r2-amend-changelog.sh

# RELEASING 3: Create the release PR.
r3-create-pr:
bash assets/releasing/r3-create-pr.sh

# RELEASING 4: Publish a git tag and GitHub release.
r4-publish:
bash assets/releasing/r4-publish.sh

# RELEASING 5: Create the merge-back-to-main PR.
r5-merge-back:
bash assets/releasing/r5-merge-back.sh
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "globus-registered-api"
version = "1.0.0"
version = "1.0.1"
description = "Manage Registered APIs in the Globus Flows service"
authors = [
{ name = "Kurt McKee", email = "support@globus.org" },
Expand Down
13 changes: 8 additions & 5 deletions src/globus_registered_api/commands/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import click

from globus_registered_api.config import GRAConfig
from globus_registered_api.manifest import ComputedRegisteredAPI
from globus_registered_api.manifest import GRAManifest
from globus_registered_api.manifest import RegisteredAPIManifest
from globus_registered_api.openapi import process_target
from globus_registered_api.openapi.enricher import OpenAPIEnricher
from globus_registered_api.openapi.loader import load_openapi_spec
Expand Down Expand Up @@ -49,7 +49,7 @@ def build_command() -> None:

def _compute_registered_apis_for_stage(
config: GRAConfig, stage: str
) -> dict[str, ComputedRegisteredAPI]:
) -> dict[str, RegisteredAPIManifest]:
stage_config = config.stages[stage]
GlobusClientRepository.instance().environment = stage_config.globus_environment

Expand All @@ -60,11 +60,14 @@ def _compute_registered_apis_for_stage(
enriched_spec = OpenAPIEnricher(config, stage).enrich(openapi_spec)

# Process each target
registered_apis: dict[str, ComputedRegisteredAPI] = {}
registered_apis: dict[str, RegisteredAPIManifest] = {}
for alias, target_config in config.targets.items():
if target_config.stages == "*" or stage in target_config.stages:
result = process_target(enriched_spec, target_config.specifier)
registered_apis[alias] = ComputedRegisteredAPI(
target=result.target, description=target_config.description
registered_apis[alias] = RegisteredAPIManifest(
target=result.target,
description=target_config.description,
data_templates=target_config.data_templates,
state_input_schema=target_config.state_input_schema,
)
return registered_apis
6 changes: 3 additions & 3 deletions src/globus_registered_api/commands/publish/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

from globus_registered_api.config import GRAConfig
from globus_registered_api.config import StageConfig
from globus_registered_api.manifest import ComputedRegisteredAPI
from globus_registered_api.manifest import GRAManifest
from globus_registered_api.manifest import RegisteredAPIManifest


@dataclass
Expand All @@ -25,10 +25,10 @@ def stage_config(self) -> StageConfig:
return self.config.stages[self.stage]

@property
def registered_apis(self) -> dict[str, ComputedRegisteredAPI]:
def registered_apis(self) -> dict[str, RegisteredAPIManifest]:
"""
Access point for registered apis in the current stage.

:return: A mapping of API aliases to ComputedRegisteredAPIs
:return: A mapping of API aliases to RegisteredAPIManifests.
"""
return self.manifest.registered_apis[self.stage]
Loading
Loading