lucasvieirasilva / nx-plugins

NX Plugins
MIT License
88 stars 15 forks source link

Support to Semantic Release #122

Open xavidop opened 1 year ago

xavidop commented 1 year ago

Description

This is by far the best python monorepo solution that exists out there. However, the automation to release a package by updating the package versions and then publishing to a repo is not supported.

Motivation

It will automate the last piece that I think this plugin is missing: release

Suggested Implementation

I would suggest to use this: https://python-semantic-release.readthedocs.io/en/latest/ So it can detects the next version of each package.

lucasvieirasilva commented 1 year ago

@xavidop thanks for the suggestion, I've never used python-semantic-release before, so I need to do some research, I'll let you know when I have some to discuss about this issue.

xavidop commented 1 year ago

Perfect! If you need more information please let me know!

lucasvieirasilva commented 1 year ago

@xavidop I've raised an issue in the python-semantic-release https://github.com/python-semantic-release/python-semantic-release/issues/614, this feature is required for us to use the semantic release considering the local dependencies.

Let's see what they think about the suggestion.

xavidop commented 1 year ago

@lucasvieirasilva that sounds fantastic!

I've implemented this junky bash script that detects the packages that were modified and bumps their versions:

#!/bin/bash

commit_message=$(git log -1 --pretty=%B)
files_changed=$(git diff HEAD^ --name-only )
changes=false

if [[ $commit_message == *"chore(publish):"* ]]; then
  echo "No changes to publish"
  exit 0
fi

# Bump version of all packages
for i in **/*/pyproject.toml; do
  pacakge_folder=$(dirname $i)
  package_name=$(basename $pacakge_folder)

  if [[ $files_changed == *"$package_name"* ]]; then
    echo "Publishing $pacakge_folder"
    cd $pacakge_folder
    poetry version minor
    # we need to rebuild with the latest versions generated by poetry
    npx nx run $package_name:build
    cd ../../
    changes=true
  fi
done

# Commit and push
if [[ $changes == true ]]; then
  git add .
  git commit -m "chore(publish): bump version"
  git push origin master
fi

# Create tag
for i in **/*/pyproject.toml; do
  pacakge_folder=$(dirname $i)
  package_name=$(basename $pacakge_folder)
  if [[ $files_changed == *"$package_name"* ]]; then
    cd $pacakge_folder
    # tag format: @voiceflow/parser@1.0.0
    tag="@voiceflow/$package_name@$(poetry version | awk '{print $2}')"
    echo "Creating tag $tag"
    git tag -a "$tag" -m "chore(publish): Publishing new version $tag [skip ci]"
    cd ../../
  fi
done

# Push to master
if [[ $changes == true ]]; then
  git push origin master --tags
  git push --tags
fi

The tag version format is the same that uses lerna or turborepo: @org>/<package>@<version, for example: @voiceflow/parser@1.0.0

lucasvieirasilva commented 1 year ago

@xavidop nice, let's hope they agree with the suggestion, so you don't need to use this script anymore!

gamoreli commented 4 months ago

NX now has a release that allows us to create Git releases using semantics. However, I was only able to update the 'package.json' version for now. It would be great to have an implementation to update the 'pyproject.toml' file instead. More here versioning-and-releasing-packages-in-a-monorepo

lucasvieirasilva commented 4 months ago

@gamoreli Hey, I was looking at their implementation, and looks like it's definitely possible to implement that, I'm gonna have a look at this in the next weeks, many thanks for the suggestion.

lucasvieirasilva commented 2 months ago

I recently experimented a little bit with the Nx release feature and it seems very immature yet, I've also recently implemented an automated release process using this plugin with release-it package.

I'm gonna leave here some references from my implementation:

Repository: vm-x-ai-sdk Project's release-it config: packages/python/.release-it.js Project's Nx target: packages/python/project.json NPM packages: package.json#1 and package.json#2

Plus

GitHub Actions

and I've used GitHub actions: .github/workflows/release.yml

By default, the github token can't push commits on branches that have branch protection rules configured, so, I resolved that by performing the following actions:

  1. creating a GitHub app with the following permissions:

And I've also created a private key for this app:

Here is some reference: https://docs.github.com/en/apps/creating-github-apps/about-creating-github-apps/about-creating-github-apps

  1. Created two organization secrets:
  1. On the branch protection rules / Protect matching branches / Allow specified actors to bypass required pull requests, select the github app that I've created.

Like this:

image

Hope that help you guys!!

LockedThread commented 1 month ago

A significant portion of my monorepo is written in Rust and we use monodon as our nx plugin for Rust. It would be amazing if you integrated the native "Nx release" feature with your plugin so that people don't have to make significant changes to their CI/CD to use your plugin. I would be willing to collaborate. See this for an example impl.

LockedThread commented 1 month ago

I found a stupid-simple solution to my problem. I can add the following to my project.json files then run nx run-many --projects=tag:type:python -t set-python-version --args="$NEW_VERSION" where $NEW_VERSION is the updated version, given to me by nx release.

  "tags": ["type:python"],
  "targets": {
    "set-python-version": {
      "executor": "@nxlv/python:run-commands",
      "options": {
        "command": "poetry version",
        "cwd": "apps/project_name"
      }
    },
   ...
}