Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split antsibull-build's single subcommand into prepare and rebuild-single; deprecate multiple #341

Merged
46 changes: 27 additions & 19 deletions docs/build-ansible.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,13 @@ All alpha releases and the first beta
# Generate the list of compatible versions.
antsibull-build new-ansible 3.0.0a1 --data-dir ansible-build-data/3

# Prepare the ansible release
# (This generates the dependency file and updates changelog.yaml)
antsibull-build prepare 3.0.0a1 --data-dir ansible-build-data/3

# Create the ansible release
# (This generates a single tarball for ansible with a dep on the ansible-base package)
antsibull-build single 3.0.0a1 --data-dir ansible-build-data/3 --sdist-dir built --debian
# (This generates a single tarball for ansible with a dep on the ansible-core package)
antsibull-build rebuild-single 3.0.0a1 --data-dir ansible-build-data/3 --sdist-dir built --debian


Setup for the first beta release
Expand Down Expand Up @@ -102,9 +106,13 @@ Beta2 up to and including rc1
rm -rf built
mkdir built

# Prepare the ansible release
# (This generates the dependency file and updates changelog.yaml)
antsibull-build prepare 3.0.0b2 --feature-frozen --data-dir ansible-build-data/3

# Create the ansible release
# (This generates a single tarball for ansible with a dep on the ansible-base package)
antsibull-build single 3.0.0b2 --feature-frozen --data-dir ansible-build-data/3 --sdist-dir built --debian
# (This generates a single tarball for ansible with a dep on the ansible-core package)
antsibull-build rebuild-single 3.0.0b2 --data-dir ansible-build-data/3 --sdist-dir built --debian


Any subsequent rcs and final
Expand All @@ -115,10 +123,10 @@ Any subsequent rcs and final
# Copy the previous rc's .deps file to the new rc version
cp ansible-build-data/3/ansible-3.0.0rc1.deps ansible-build-data/3/ansible-3.0.0rc2.deps

# We do not run antsibull-build single because the compatible collection version information
# We do not run antsibull-build prepare because the compatible collection version information
# is now set until final.
# * Change the _ansible_version field to the new version
# * If ansible-base needs a version update, change it in the .build and .deps file.
# * If ansible-core needs a version update, change it in the .build and .deps file.
# * If any collections have been granted an update exception, change the range manually in the
# .build and .deps file.
# vim ansible-build-data/3/ansible-3.build
Expand All @@ -137,19 +145,19 @@ New minor releases (3.Y.0)
rm -rf built
mkdir built

# Create the ansible release
# (This generates a single tarball for ansible with a dep on the ansible-base package)
antsibull-build single 3.1.0 --data-dir ansible-build-data/3 --sdist-dir built --debian
# Prepare the ansible release
# (This generates the dependency file and updates changelog.yaml)
antsibull-build prepare 3.1.0 --data-dir ansible-build-data/3

# Until we get separate versions for ansible-base working correctly:
# Until we get separate versions for ansible-core working correctly:
# https://github.com/ansible-community/antsibull/issues/187
# We'll need to update the ansible-base version manually and then rebuild the release. Follow
# these steps after running antsibull-build single above:
# We'll need to update the ansible-core version manually. Follow
# these steps after running antsibull-build prepare above:
# vim ansible-build-data/3/ansible-3.1.0.deps
# Change the ansible-base version information in here to the latest compatible version on pypi
# Change the ansible-core version information in here to the latest compatible version on pypi

rm -rf built
mkdir built
# Create the ansible release
# (This generates a single tarball for ansible with a dep on the ansible-core package)
antsibull-build rebuild-single 3.1.0 --data-dir ansible-build-data/3 --build-file ansible-3.build --deps-file ansible-3.1.0.deps --sdist-dir built --debian


Expand Down Expand Up @@ -192,8 +200,8 @@ We want to sync docs and releases. So the first thing to do is to alert the doc
``#ansible-docs`` that we're making a release (they should know ahead of time if they're watching the
schedule too).

* In patch releases, check the porting guide for unwanted breaking changes (collections that are new
in this patch release are allowed to have breaking changes but existing collections should not.)
* In minor/patch releases, check the porting guide for unwanted (breaking) changes (collections that are
new in this patch release are allowed to have breaking changes but existing collections should not.)

* Fixing this requires manually changing the .deps file and re-running rebuild-single (and then
pinging the collection maintainer to find out what should happen for the next release.)
Expand Down Expand Up @@ -232,7 +240,7 @@ Update the topic in the #ansible channel with the new version
TODO
====

* Right now the script assumes ansible-base and ansible will have the same version. This is true
for 2.10 and possibly for 3 but in the longer term ansible-base major releases are going to
* Right now the script assumes ansible-core and ansible will have the same version. This is true
for 2.10 and possibly for 3 but in the longer term ansible-core major releases are going to
slow down while ansible releases may speed up slightly. We'll need to adapt the script to handle
these diverged versions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ aiocontextvars = {version = "*", python = "~3.6"}
aiofiles = "*"
aiohttp = ">= 3.0.0"
ansible-pygments = "*"
antsibull-changelog = ">= 0.7.0"
antsibull-changelog = ">= 0.10.0"
asyncio-pool = "*"
docutils = "*"
importlib-metadata = {version = "*", python = "<3.8"}
Expand Down
6 changes: 2 additions & 4 deletions roles/build-release/tasks/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@
_feature_freeze: "--feature-frozen"
when: antsibull_ansible_version is regex("^\d+.\d+.\d+(b2|b3|rc1)$")

- name: Build a release with new dependencies
- name: Prepare a release with new dependencies
command: >-
poetry run coverage run -p --source antsibull -m antsibull.cli.antsibull_build single {{ antsibull_ansible_version }}
poetry run coverage run -p --source antsibull -m antsibull.cli.antsibull_build prepare {{ antsibull_ansible_version }}
--data-dir {{ antsibull_data_dir }}
--sdist-dir {{ antsibull_sdist_dir }}
--debian
{{ _feature_freeze | default('') }}
# Minimal failure tolerance to galaxy collection download errors
retries: 3
Expand Down
168 changes: 87 additions & 81 deletions src/antsibull/build_ansible_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,88 +207,17 @@ def write_build_script(ansible_version: PypiVer,
os.chmod(build_ansible_filename, mode=0o755)


def build_single_impl(dependency_data: DependencyFileData, add_release: bool = True) -> None:
app_ctx = app_context.app_ctx.get()

# Determine included collection versions
ansible_base_version = PypiVer(dependency_data.ansible_base_version)
included_versions = {
collection: SemVer(version)
for collection, version in dependency_data.deps.items()
}

with tempfile.TemporaryDirectory() as tmp_dir:
download_dir = os.path.join(tmp_dir, 'collections')
os.mkdir(download_dir, mode=0o700)

# Download included collections
asyncio.run(download_collections(included_versions, app_ctx.galaxy_url,
download_dir, app_ctx.extra['collection_cache']))

# Get Ansible changelog, add new release
ansible_changelog = ChangelogData.ansible(
app_ctx.extra['data_dir'], app_ctx.extra['dest_data_dir'])
if add_release:
date = datetime.date.today()
ansible_changelog.add_ansible_release(
str(app_ctx.extra['ansible_version']),
date,
f'Release Date: {date}'
f'\n\n'
f'`Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`_')

# Get changelog and porting guide data
changelog = get_changelog(
app_ctx.extra['ansible_version'],
deps_dir=app_ctx.extra['data_dir'],
deps_data=[dependency_data],
collection_cache=app_ctx.extra['collection_cache'],
ansible_changelog=ansible_changelog)

# Create package and collections directories
package_dir = os.path.join(tmp_dir, f'ansible-{app_ctx.extra["ansible_version"]}')
os.mkdir(package_dir, mode=0o700)
ansible_collections_dir = os.path.join(package_dir, 'ansible_collections')
os.mkdir(ansible_collections_dir, mode=0o700)

# Write the ansible release info to the collections dir
write_release_py(app_ctx.extra['ansible_version'], ansible_collections_dir)

# Install collections
# TODO: PY3.8:
# collections_to_install = [p for f in os.listdir(download_dir)
# if os.path.isfile(p := os.path.join(download_dir, f))]
collections_to_install = []
for collection in os.listdir(download_dir):
path = os.path.join(download_dir, collection)
if os.path.isfile(path):
collections_to_install.append(path)

asyncio.run(install_together(collections_to_install, ansible_collections_dir))

# Compose and write release notes
release_notes = ReleaseNotes.build(changelog)
release_notes.write_changelog_to(package_dir)
release_notes.write_porting_guide_to(package_dir)

# Write build scripts and files
write_build_script(app_ctx.extra['ansible_version'], ansible_base_version, package_dir)
write_python_build_files(app_ctx.extra['ansible_version'], ansible_base_version, '',
package_dir, release_notes, app_ctx.extra['debian'])
if app_ctx.extra['debian']:
write_debian_directory(app_ctx.extra['ansible_version'], ansible_base_version,
package_dir)
make_dist(package_dir, app_ctx.extra['sdist_dir'])

# Write changelog and porting guide also to destination directory
release_notes.write_changelog_to(app_ctx.extra['dest_data_dir'])
release_notes.write_porting_guide_to(app_ctx.extra['dest_data_dir'])
def build_single_command() -> int:
# This is deprecated; in the future users will have to first run prepare, and then
# rebuild-single.
result = prepare_command()
if result != 0:
return result

if add_release:
ansible_changelog.changes.save()
return rebuild_single_command()


def build_single_command() -> int:
def prepare_command() -> int:
app_ctx = app_context.app_ctx.get()

build_filename = os.path.join(app_ctx.extra['data_dir'], app_ctx.extra['build_file'])
Expand Down Expand Up @@ -337,8 +266,19 @@ def build_single_command() -> int:
str(ansible_base_version),
{collection: str(version) for collection, version in included_versions.items()})

build_single_impl(dependency_data)
# Get Ansible changelog, add new release
ansible_changelog = ChangelogData.ansible(
app_ctx.extra['data_dir'], app_ctx.extra['dest_data_dir'])
date = datetime.date.today()
ansible_changelog.add_ansible_release(
str(app_ctx.extra['ansible_version']),
date,
f'Release Date: {date}'
f'\n\n'
f'`Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`_')
ansible_changelog.changes.save()

# Write dependency file
deps_filename = os.path.join(app_ctx.extra['dest_data_dir'], app_ctx.extra['deps_file'])
deps_file = DepsFile(deps_filename)
deps_file.write(
Expand All @@ -356,7 +296,73 @@ def rebuild_single_command() -> int:
deps_file = DepsFile(deps_filename)
dependency_data = deps_file.parse()

build_single_impl(dependency_data, add_release=False)
# Determine included collection versions
ansible_base_version = PypiVer(dependency_data.ansible_base_version)
included_versions = {
collection: SemVer(version)
for collection, version in dependency_data.deps.items()
}

with tempfile.TemporaryDirectory() as tmp_dir:
download_dir = os.path.join(tmp_dir, 'collections')
os.mkdir(download_dir, mode=0o700)

# Download included collections
asyncio.run(download_collections(included_versions, app_ctx.galaxy_url,
download_dir, app_ctx.extra['collection_cache']))

# Get Ansible changelog, add new release
ansible_changelog = ChangelogData.ansible(
app_ctx.extra['data_dir'], app_ctx.extra['dest_data_dir'])

# Get changelog and porting guide data
changelog = get_changelog(
app_ctx.extra['ansible_version'],
deps_dir=app_ctx.extra['data_dir'],
deps_data=[dependency_data],
collection_cache=app_ctx.extra['collection_cache'],
ansible_changelog=ansible_changelog)

# Create package and collections directories
package_dir = os.path.join(tmp_dir, f'ansible-{app_ctx.extra["ansible_version"]}')
os.mkdir(package_dir, mode=0o700)
ansible_collections_dir = os.path.join(package_dir, 'ansible_collections')
os.mkdir(ansible_collections_dir, mode=0o700)

# Write the ansible release info to the collections dir
write_release_py(app_ctx.extra['ansible_version'], ansible_collections_dir)

# Install collections
# TODO: PY3.8:
# collections_to_install = [p for f in os.listdir(download_dir)
# if os.path.isfile(p := os.path.join(download_dir, f))]
collections_to_install = []
for collection in os.listdir(download_dir):
path = os.path.join(download_dir, collection)
if os.path.isfile(path):
collections_to_install.append(path)

asyncio.run(install_together(collections_to_install, ansible_collections_dir))

# Compose and write release notes to destination directory
release_notes = ReleaseNotes.build(changelog)
release_notes.write_changelog_to(package_dir)
release_notes.write_porting_guide_to(package_dir)

# Write changelog and porting guide also to destination directory
release_notes.write_changelog_to(app_ctx.extra['dest_data_dir'])
release_notes.write_porting_guide_to(app_ctx.extra['dest_data_dir'])

# Write build scripts and files
write_build_script(app_ctx.extra['ansible_version'], ansible_base_version, package_dir)
write_python_build_files(app_ctx.extra['ansible_version'], ansible_base_version, '',
package_dir, release_notes, app_ctx.extra['debian'])
if app_ctx.extra['debian']:
write_debian_directory(app_ctx.extra['ansible_version'], ansible_base_version,
package_dir)

# Create source distribution
make_dist(package_dir, app_ctx.extra['sdist_dir'])

return 0

Expand Down
3 changes: 2 additions & 1 deletion src/antsibull/changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ def concatenate(cls, changelogs: t.List['ChangelogData']) -> 'ChangelogData':

def add_ansible_release(self, version: str, date: datetime.date, release_summary: str) -> None:
add_release(self.config, self.changes, [], [], version,
codename=None, date=date, update_existing=True)
codename=None, date=date, update_existing=True,
show_release_summary_warning=False)
release_date = self.changes.releases[version]
if 'changes' not in release_date:
release_date['changes'] = {}
Expand Down
Loading