1+ # LocalStack specific workflow to implement a fully-integrated continuous integration pipeline for our fork
2+ # - Rebase this fork based on the latest commit on `main` of upstream
3+ # - Build a Python source and wheel distribution of moto-ext with deterministic versioning
4+ # - Publish the distributions to PyPi
5+ # - Tag the commit in this fork with the new version
6+ # - Create a GitHub release for the new version
7+
8+ name : Sync / Release moto-ext
9+
10+ on :
11+ # TODO remove this trigger after testing
12+ push :
13+ workflow_dispatch :
14+ inputs :
15+ dry_run :
16+ description : ' Dry Run?'
17+ default : true
18+ required : true
19+ type : boolean
20+
21+ # limit concurrency to 1
22+ concurrency :
23+ group : ${{ github.workflow }}
24+
25+ permissions :
26+ contents : write
27+
28+ jobs :
29+ sync-build-release-moto-ext :
30+ runs-on : ubuntu-latest
31+ environment :
32+ name : pypi
33+ url : https://pypi.org/project/moto-ext/
34+ steps :
35+ - name : Checkout
36+ uses : actions/checkout@v4
37+ with :
38+ fetch-depth : 0
39+ ref : localstack
40+
41+ - name : Setup Python
42+ uses : actions/setup-python@v6
43+ with :
44+ python-version : ' 3.13'
45+
46+ - name : Rebase localstack branch with latest master from upstream
47+ run : |
48+ # Configure git
49+ git config --global user.name 'LocalStack Bot'
50+ git config --global user.email 'localstack-bot@users.noreply.github.com'
51+
52+ # make sure to switch to the `localstack` branch (default / main branch of this fork)
53+ git switch localstack
54+ # add moto upstream as remote
55+ git remote add upstream git@github.com:getmoto/moto.git
56+ # rebase with latest changes
57+ git pull
58+ git fetch upstream
59+ git rebase upstream/master
60+
61+ - name : Determine new version
62+ run : |
63+ echo "Determining new version..."
64+ cat > setuptools.cfg << EOF
65+ [tool.setuptools_scm]
66+ local_scheme = "no-local-version"
67+ EOF
68+ python3 -m venv .venv
69+ source .venv/bin/activate
70+ python3 -m pip install setuptools_scm build
71+ NEW_VERSION=$(python3 -m setuptools_scm -c setuptools.cfg)
72+ NEW_VERSION="${NEW_VERSION//dev/post}"
73+ echo "New version is: $NEW_VERSION"
74+ echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_ENV
75+
76+ - name : Build Python distributions
77+ # FYI: Checks in this script only work because the -e flag is enabled by default in GitHub actions
78+ run : |
79+ echo "Setting new version in setup.cfg":
80+ # make sure setup.cfg is not dirty yet
81+ git diff --exit-code setup.cfg
82+ sed -i -E 's/^(version\s*=\s*)("?)[^"]+("?)/\1\2'"$NEW_VERSION"'\3/' setup.cfg
83+ # make sure setup.cfg is dirty now
84+ ! git diff --exit-code setup.cfg
85+
86+ echo "Building new version and tagging commit..."
87+ python3 -m build
88+
89+ - name : Tag successful build
90+ run : |
91+ git tag -a $NEW_VERSION -m $NEW_VERSION
92+
93+ - name : Clean up
94+ run : |
95+ git reset --hard
96+ git clean -df
97+
98+ - name : Store built distributions
99+ uses : actions/upload-artifact@v4
100+ with :
101+ name : moto-ext-dists
102+ path : dist/*.*
103+
104+ # publish the package before pushing the tag (this might fail if the version already exists on PyPI)
105+ - name : Publish package distributions to PyPI
106+ if : ${{ github.event.inputs.dry_run == false }}
107+ run : |
108+ echo "Ensure that this is really only triggered if dry run is explicitly set to false"
109+ # uses: pypa/gh-action-pypi-publish@release/v1
110+
111+ - name : Push & Create Release
112+ if : ${{ github.event.inputs.dry_run == false }}
113+ run : |
114+ echo "Ensure that this is really only triggered if dry run is explicitly set to false"
115+ # git push --force-with-lease
116+ # git push --atomic origin localstack $NEW_VERSION
117+ # gh release create $NEW_VERSION
0 commit comments