Skip to content

Commit

Permalink
Add support of node packages
Browse files Browse the repository at this point in the history
  • Loading branch information
sbrunner committed Nov 19, 2024
1 parent 8739d36 commit 80c6646
Show file tree
Hide file tree
Showing 5 changed files with 265 additions and 6 deletions.
13 changes: 12 additions & 1 deletion config.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ _Tag Publish configuration file_
- **`tag_to_version_re`**: Refer to _[#/definitions/version_transform](#definitions/version_transform)_.
- **`docker`**: Refer to _[#/definitions/docker](#definitions/docker)_.
- **`pypi`**: Refer to _[#/definitions/pypi](#definitions/pypi)_.
- **`node`**: Refer to _[#/definitions/node](#definitions/node)_.
- **`helm`**: Refer to _[#/definitions/helm](#definitions/helm)_.
- **`dispatch`** _(array)_: Default: `[]`.
- **Items** _(object)_: Send a dispatch event to an other repository. Default: `{}`.
Expand All @@ -25,7 +26,7 @@ _Tag Publish configuration file_
- **`name`** _(string)_: The image name.
- **`tags`** _(array)_: The tag name, will be formatted with the version=<the version>, the image with version=latest should be present when we call the tag-publish script. Default: `["{version}"]`.
- **Items** _(string)_
- **`repository`** _(object)_: The repository where we should publish the images. Can contain additional properties. Default: `{"github": {"server": "ghcr.io", "versions": ["version_tag", "version_branch", "rebuild"]}, "dockerhub": {}}`.
- **`repository`** _(object)_: The repository where we should publish the images. Can contain additional properties. Default: `{"github": {"server": "ghcr.io", "versions": ["version_tag", "version_branch", "rebuild"]}}`.
- **Additional properties** _(object)_
- **`server`** _(string)_: The server URL.
- **`versions`** _(array)_: The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script. Default: `["version_tag", "version_branch", "rebuild", "feature_branch"]`.
Expand All @@ -51,6 +52,16 @@ _Tag Publish configuration file_
- **Items** _(string)_
- **`versions`** _(array)_: The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script. Default: `["version_tag"]`.
- **Items** _(string)_
- <a id="definitions/node"></a>**`node`** _(object)_: Configuration to publish on node.
- **`packages`** _(array)_: The configuration of packages that will be published.
- **Items** _(object)_: The configuration of package that will be published.
- **`group`** _(string)_: The image is in the group, should be used with the --group option of tag-publish script. Default: `"default"`.
- **`folder`** _(string)_: The folder of the node package. Default: `"."`.
- **`versions`** _(array)_: The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script. Default: `["version_tag"]`.
- **Items** _(string)_
- **`repository`** _(object)_: The packages repository where we should publish the packages. Can contain additional properties. Default: `{"github": {"server": "npm.pkg.github.com"}}`.
- **Additional properties** _(object)_
- **`server`** _(string)_: The server URL.
- <a id="definitions/helm"></a>**`helm`** _(object)_: Configuration to publish Helm charts on GitHub release.
- **`folders`** _(array)_: The folders that will be published.
- **Items** _(string)_
Expand Down
35 changes: 35 additions & 0 deletions tag_publish/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ def main() -> None:
success &= _handle_pypi_publish(
args.group, args.dry_run, config, version, version_type, github, published_payload
)
success &= _handle_node_publish(
args.group, args.dry_run, config, version, version_type, published_payload
)
success &= _handle_docker_publish(
args.group,
args.dry_run,
Expand Down Expand Up @@ -232,6 +235,38 @@ def _handle_pypi_publish(
return success


def _handle_node_publish(
group: str,
dry_run: bool,
config: tag_publish.configuration.Configuration,
version: str,
version_type: str,
published_payload: list[tag_publish.PublishedPayload],
) -> bool:
success = True
node_config = config.get("node", {})
if node_config:
for package in node_config.get("packages", []):
if package.get("group", tag_publish.configuration.PIP_PACKAGE_GROUP_DEFAULT) == group:
publish = version_type in node_config.get(
"versions", tag_publish.configuration.PYPI_VERSIONS_DEFAULT
)
folder = package.get("folder", tag_publish.configuration.PYPI_PACKAGE_FOLDER_DEFAULT)
for repo_name, repo_config in node_config.get("repository", {}).items():
if dry_run:
print(
f"{'Publishing' if publish else 'Checking'} '{folder}' to {repo_name}, "
"skipping (dry run)"
)
else:
success &= tag_publish.publish.node(
package, version, version_type, repo_config, publish
)
if publish:
published_payload.append({"type": "node", "folder": folder})
return success


def _handle_docker_publish(
group: str,
dry_run: bool,
Expand Down
92 changes: 89 additions & 3 deletions tag_publish/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ class Configuration(TypedDict, total=False):
Configuration to publish on pypi
"""

node: "Node"
"""
node.
Configuration to publish on node
"""

helm: "Helm"
"""
helm.
Expand Down Expand Up @@ -82,8 +89,7 @@ class Configuration(TypedDict, total=False):


DOCKER_REPOSITORY_DEFAULT = {
"github": {"server": "ghcr.io", "versions": ["version_tag", "version_branch", "rebuild"]},
"dockerhub": {},
"github": {"server": "ghcr.io", "versions": ["version_tag", "version_branch", "rebuild"]}
}
""" Default value of the field path 'Docker repository' """

Expand Down Expand Up @@ -152,7 +158,6 @@ class Docker(TypedDict, total=False):
The repository where we should publish the images
default:
dockerhub: {}
github:
server: ghcr.io
versions:
Expand Down Expand Up @@ -245,6 +250,87 @@ class Helm(TypedDict, total=False):
"""


NODE_PACKAGE_FOLDER_DEFAULT = "."
""" Default value of the field path 'node package folder' """


NODE_PACKAGE_GROUP_DEFAULT = "default"
""" Default value of the field path 'node package group' """


NODE_REPOSITORY_DEFAULT = {"github": {"server": "npm.pkg.github.com"}}
""" Default value of the field path 'node repository' """


NODE_VERSIONS_DEFAULT = ["version_tag"]
""" Default value of the field path 'node versions' """


class Node(TypedDict, total=False):
"""
node.
Configuration to publish on node
"""

packages: List["NodePackage"]
""" The configuration of packages that will be published """

versions: List[str]
"""
node versions.
The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script
default:
- version_tag
"""

repository: Dict[str, "NodeRepository"]
"""
Node repository.
The packages repository where we should publish the packages
default:
github:
server: npm.pkg.github.com
"""


class NodePackage(TypedDict, total=False):
"""
node package.
The configuration of package that will be published
"""

group: str
"""
node package group.
The image is in the group, should be used with the --group option of tag-publish script
default: default
"""

folder: str
"""
node package folder.
The folder of the node package
default: .
"""


class NodeRepository(TypedDict, total=False):
"""Node repository."""

server: str
""" The server URL """


PIP_PACKAGE_GROUP_DEFAULT = "default"
""" Default value of the field path 'pypi package group' """

Expand Down
68 changes: 68 additions & 0 deletions tag_publish/publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import datetime
import glob
import json
import os
import re
import subprocess # nosec
Expand Down Expand Up @@ -103,6 +104,73 @@ def pip(
return True


def node(
package: tag_publish.configuration.NodePackage,
version: str,
version_type: str,
repo_config: tag_publish.configuration.NodeRepository,
publish: bool,
) -> bool:
"""
Publish to npm.
Arguments:
version: The version that will be published
version_type: Describe the kind of release we do: rebuild (specified using --type), version_tag,
version_branch, feature_branch, feature_tag (for pull request)
repo_config: The repository configuration
publish: If False only check the package
package: The package configuration
github: The GitHub helper
"""
del version_type

folder = package.get("folder", tag_publish.configuration.PYPI_PACKAGE_FOLDER_DEFAULT)
print(f"::group::{'Publishing' if publish else 'Checking'} '{folder}' to npm")
sys.stdout.flush()
sys.stderr.flush()

try:
with open(os.path.join(folder, "package.json"), encoding="utf-8") as open_file:
package_json = json.loads(open_file.read())
package_json["version"] = version
with open(os.path.join(folder, "package.json"), "w", encoding="utf-8") as open_file:
open_file.write(json.dumps(package_json, indent=2) + "\n")

cwd = os.path.abspath(folder)

is_github = repo_config["server"] == "npm.pkg.github.com"
old_npmrc = None
npmrc_filename = os.path.expanduser("~/.npmrc")
env = {**os.environ}
if is_github:
old_npmrc = None
if os.path.exists(npmrc_filename):
with open(npmrc_filename, encoding="utf-8") as open_file:
old_npmrc = open_file.read()
with open(npmrc_filename, "w", encoding="utf-8") as open_file:
open_file.write(f"registry=https://{repo_config['server']}\n")
open_file.write("always-auth=true\n")
env["NODE_AUTH_TOKEN"] = os.environ["GITHUB_TOKEN"]

subprocess.run(["npm", "publish", *([] if publish else ["--dry-run"])], cwd=cwd, check=True, env=env)

if is_github:
if old_npmrc is None:
os.remove(npmrc_filename)
else:
with open(npmrc_filename, "w", encoding="utf-8") as open_file:
open_file.write(old_npmrc)
print("::endgroup::")
except subprocess.CalledProcessError as exception:
print(f"Error: {exception}")
print("::endgroup::")
print("::error::With error")
return False
return True


def docker(
config: tag_publish.configuration.DockerRepository,
name: str,
Expand Down
63 changes: 61 additions & 2 deletions tag_publish/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@
"github": {
"server": "ghcr.io",
"versions": ["version_tag", "version_branch", "rebuild"]
},
"dockerhub": {}
}
},
"type": "object",
"additionalProperties": {
Expand Down Expand Up @@ -165,6 +164,65 @@
}
}
},
"node": {
"title": "node",
"description": "Configuration to publish on node",
"type": "object",
"properties": {
"packages": {
"description": "The configuration of packages that will be published",
"type": "array",
"items": {
"title": "node package",
"description": "The configuration of package that will be published",
"type": "object",
"properties": {
"group": {
"description": "The image is in the group, should be used with the --group option of tag-publish script",
"title": "node package group",
"default": "default",
"type": "string"
},
"folder": {
"title": "node package folder",
"description": "The folder of the node package",
"type": "string",
"default": "."
}
}
}
},
"versions": {
"title": "node versions",
"description": "The kind or version that should be published, tag, branch or value of the --version argument of the tag-publish script",
"type": "array",
"default": ["version_tag"],
"items": {
"type": "string"
}
},
"repository": {
"title": "Node repository",
"description": "The packages repository where we should publish the packages",
"default": {
"github": {
"server": "npm.pkg.github.com"
}
},
"type": "object",
"additionalProperties": {
"title": "Node repository",
"type": "object",
"properties": {
"server": {
"description": "The server URL",
"type": "string"
}
}
}
}
}
},
"helm": {
"title": "helm",
"description": "Configuration to publish Helm charts on GitHub release",
Expand Down Expand Up @@ -219,6 +277,7 @@
},
"docker": { "$ref": "#/definitions/docker" },
"pypi": { "$ref": "#/definitions/pypi" },
"node": { "$ref": "#/definitions/node" },
"helm": { "$ref": "#/definitions/helm" },
"dispatch": {
"title": "Dispatch",
Expand Down

0 comments on commit 80c6646

Please sign in to comment.