1- # LocalStack specific workflow to implement a fully-integrated continuous integration pipeline for our fork
1+ # LocalStack specific workflow to implement a fully-integrated continuous integration pipeline for Moto-Ext
22# - 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
73
8- name : Sync / Release moto-ext
4+ name : Sync moto-ext with upstream
95
106on :
11- schedule :
12- - cron : 0 5 * * MON
137 workflow_dispatch :
148 inputs :
159 dry_run :
16- description : ' Dry Run? '
10+ description : ' Dry run '
1711 default : true
1812 required : true
1913 type : boolean
14+ # TODO: remove
15+ pull_request :
2016
21- # limit concurrency to 1
17+ # Limit concurrency to 1
2218concurrency :
2319 group : ${{ github.workflow }}
2420
2521jobs :
26- sync-build-release- moto-ext :
22+ sync-moto-ext :
2723 runs-on : ubuntu-latest
28- environment :
29- name : pypi
30- url : https://pypi.org/project/moto-ext/
3124 permissions :
3225 contents : write
3326 id-token : write
@@ -50,35 +43,35 @@ jobs:
5043 git config --global user.name 'LocalStack Bot'
5144 git config --global user.email '[email protected] ' 5245 git remote set-url origin https://git:${{ secrets.PRO_ACCESS_TOKEN }}@github.com/${{ github.repository }}
53-
46+
5447 # make sure to switch to the `localstack` branch (default / main branch of this fork)
5548 git switch localstack
5649 # add moto upstream as remote
5750 git remote add upstream https://github.com/getmoto/moto.git
5851 # rebase with latest changes
5952 git pull
60-
53+
6154 # Create a custom merge driver which prefers everything from upstream _BUT_ the name and the URL
6255 mkdir -p $HOME/.local/bin
6356 cat > $HOME/.local/bin/git-prefer-theirs-name-url << EOF
6457 #!/bin/bash
6558 set -e
66-
59+
6760 base="\$1"
6861 local="\$2"
6962 remote="\$3"
70-
63+
7164 echo "Executing custom merge driver for base \$base, local \$local, remote \$remote."
72-
65+
7366 # Define keys to keep
7467 KEYS=("name" "url")
75-
68+
7669 # Read files into arrays
7770 mapfile -t REMOTE_LINES < "\$remote"
7871 mapfile -t LOCAL_LINES < "\$local"
79-
72+
8073 echo "merging \$local + \$local + \$remote ..."
81-
74+
8275 # Function to check if a line should be kept (matches any key)
8376 keep_line() {
8477 local line="\$1"
8780 done
8881 return 1
8982 }
90-
83+
9184 # keep key-matched lines from local, others from remote
9285 for i in "\${!LOCAL_LINES[@]}"; do
9386 if keep_line "\${REMOTE_LINES[i]}"; then
@@ -96,22 +89,22 @@ jobs:
9689 echo "\${LOCAL_LINES[i]}"
9790 fi
9891 done > "\$local"
99-
92+
10093 exit 0
10194 EOF
102-
95+
10396 # make the script executable and add it to the PATH
10497 chmod +x $HOME/.local/bin/git-prefer-theirs-name-url
10598 echo "$HOME/.local/bin" >> "$GITHUB_PATH"
106-
99+
107100 # add the merge driver to the git config
108101 cat >> .git/config << EOF
109-
102+
110103 [merge "git-prefer-theirs-name-url"]
111104 name = A driver which resolves merge conflicts on a setup.cfg such that it always takes the local name and url, and everything else from upstream
112105 driver = git-prefer-theirs-name-url %O %A %B
113106 EOF
114-
107+
115108 # define to use the custom merge driver for the setup.cfg
116109 cat > .gitattributes << EOF
117110 setup.cfg merge=git-prefer-theirs-name-url
@@ -122,74 +115,10 @@ jobs:
122115 git fetch upstream
123116 git rebase -f upstream/master
124117
125- - name : Determine new version
126- run : |
127- echo "Determining new version..."
128- cat > setuptools.cfg << EOF
129- [tool.setuptools_scm]
130- local_scheme = "no-local-version"
131- version_scheme = "post-release"
132- EOF
133- python3 -m venv .venv
134- source .venv/bin/activate
135- python3 -m pip install setuptools_scm
136- NEW_VERSION=$(python3 -m setuptools_scm -c setuptools.cfg)
137- NEW_VERSION="${NEW_VERSION//dev/post}"
138- echo "New version is: $NEW_VERSION"
139- echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_ENV
140-
141- - name : Build Python distributions
142- # FYI: Checks in this script only work because the -e flag is enabled by default in GitHub actions
143- run : |
144- python3 -m pip install build
145-
146- echo "Setting new version in setup.cfg":
147- # make sure setup.cfg is not dirty yet
148- git diff --exit-code setup.cfg
149- sed -i -E 's/^(version\s*=\s*)("?)[^"]+("?)/\1\2'"$NEW_VERSION"'\3/' setup.cfg
150- # make sure setup.cfg is dirty now
151- ! git diff --exit-code setup.cfg
152-
153- echo "Building new version and tagging commit..."
154- python3 -m build
155-
156- - name : Tag successful build
157- run : |
158- git tag -a $NEW_VERSION -m $NEW_VERSION
159-
160- - name : Clean up
161- run : |
162- git reset --hard
163- git clean -df
164-
165- - name : Store built distributions
166- uses : actions/upload-artifact@v4
167- with :
168- name : moto-ext-dists
169- path : dist/*.*
170-
171- # publish the package before pushing the tag (this might fail if the version already exists on PyPI)
172- - name : Publish package distributions to PyPI
173- if : ${{ github.event.inputs.dry_run != 'true' }}
174- uses : pypa/gh-action-pypi-publish@release/v1
175-
176118 - name : Push
177119 if : ${{ github.event.inputs.dry_run != 'true' }}
178120 run : |
179121 git push --force-with-lease
180- git push --atomic origin localstack $NEW_VERSION
122+ git push --atomic origin localstack
181123 env :
182124 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
183-
184- # Add a retry to avoid issues where the GH CLI fails
185- # because it does not yet detect the pushed tag.
186- - name : Create Release
187- uses : nick-fields/retry@v3
188- if : ${{ github.event.inputs.dry_run != 'true' }}
189- env :
190- GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
191- with :
192- max_attempts : 5
193- retry_wait_seconds : 120
194- timeout_minutes : 5
195- command : gh release create $NEW_VERSION --repo localstack/moto --notes "automatic rebase sync and release"
0 commit comments