1+ #! /bin/bash
2+ # @file functions
3+ # @brief CI and local package release "automation" functions.
4+
5+ #
6+ # @description Parse and return a version value from a "package.json" file
7+ #
8+ # @see [shdoc](https://github.com/reconquest/shdoc)
9+ # @example
10+ # packageVersion "<PATH>/package.json"
11+ packageVersion () {
12+ local package_json_file=$1
13+ local version=" "
14+ while read a b ; do
15+ [ " $a " = ' "version":' ] && { b=" ${b% \" * } " ; version=" ${b# \" } " ; break ; }
16+ done < $package_json_file
17+ echo $version
18+ }
19+
20+ #
21+ # @description $PKG_ROOT environment variable check. Should be a string
22+ # with a root path of the package
23+ #
24+ # @see $PKG_ROOT
25+ checkPkgRoot () {
26+ if [ -z " $PKG_ROOT " ]
27+ then
28+ PKG_ROOT=$1
29+ if [ -z " $PKG_ROOT " ]
30+ then
31+ PKG_ROOT=" ."
32+ fi
33+ fi
34+ }
35+
36+ #
37+ # @description Replace .env (default) file content with $PKG_ROOT variable value
38+ #
39+ # @see $PKG_ROOT
40+ fixEnvFile () {
41+ # $PKG_ROOT environment variable check
42+ checkPkgRoot $1
43+
44+ # Fix env (default) file with correct value
45+ # for environment variables
46+ if [ -f " $PKG_ROOT /.env" ]
47+ then
48+ echo " [FIX .ENV] Replaced $( cat " $PKG_ROOT /.env" ) to => REPOSITORY_ROOT=."
49+ echo " REPOSITORY_ROOT=." > " $PKG_ROOT /.env"
50+ fi
51+ }
52+
53+ # @description Add github actions state and output variables to be handled on .yml workflow files
54+ #
55+ # @see $GITHUB_OUTPUT
56+ # @see [Deprecating save-state and set-output commands](https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands)
57+ # @see [Github Actions: Output parameter](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter)
58+ githubActionsOutputs () {
59+ # PS: CURRENT_TAG and COMMIT_MESSAGE are handled here as "global/environment" variables
60+ CURRENT_TAG=$( git describe --tags $( git rev-list --tags --max-count=1) )
61+ COMMIT_MESSAGE=$( git log -1 --pretty=%B)
62+
63+ echo " [GITHUB VARIABLES] Commit => $COMMIT_MESSAGE "
64+
65+ # Use the format {name}={value} instead of ::set-output
66+ echo " TAG=$CURRENT_TAG " >> $GITHUB_OUTPUT
67+ echo " COMMIT_MESSAGE=$COMMIT_MESSAGE " >> $GITHUB_OUTPUT
68+ }
69+
70+ # @description Copy all content of the package folder to the ROOT dir
71+ #
72+ # @see [shdoc](https://github.com/reconquest/shdoc)
73+ # @example
74+ # # From the root folder, with "Packages/<PACKAGE_NAME>"
75+ # copyPackagesContent
76+ # # result: Copy "Packages/<PACKAGE_NAME>/*.*" to ROOT/
77+ copyPackagesContent () {
78+ shopt -s extglob dotglob
79+
80+ cp -rvf " Packages/$PKG_NAME /." " $PKG_ROOT /"
81+ rm -rf ./Packages
82+ }
83+
84+ # TODO: Move this common function to another script file in order to reuse (e.g .github/scripts/common.sh)
85+ #
86+ # @description Rename invalid package directories to be "untracked" by game engine, adding a "~" suffix
87+ # (e.g "Samples" => "Samples~", "Documentation" => "Documentation~")
88+ #
89+ # @see $PKG_ROOT
90+ # @see [shdoc](https://github.com/reconquest/shdoc)
91+ renameInvalidDirs () {
92+ # $PKG_ROOT environment variable check
93+ checkPkgRoot $1
94+
95+ if [ $PKG_ROOT = " ./" ]
96+ then
97+ echo " [RENAME DIRECTORIES] [Error] The \$ PKG_ROOT => '$PKG_ROOT ' should be just '.' for current directory."
98+ return 1
99+ fi
100+
101+ echo " [RENAME DIRECTORIES] Package Root: $PKG_ROOT /"
102+
103+ # Rename UPM special directories with suffix "~"
104+ if [ -d " $PKG_ROOT /Samples" ] && [ ! -d " $PKG_ROOT /Samples~" ]
105+ then
106+ mv " $PKG_ROOT /Samples" " $PKG_ROOT /Samples~"
107+ rm -f " $PKG_ROOT /Samples.meta"
108+
109+ echo " [RENAMED] Samples => $PKG_ROOT /Samples~"
110+ fi
111+ if [ -d " $PKG_ROOT /Documentation" ] && [ ! -d " $PKG_ROOT /Documentation~" ]
112+ then
113+ mv " $PKG_ROOT /Documentation" " $PKG_ROOT /Documentation~"
114+ rm -f " $PKG_ROOT /Documentation.meta"
115+
116+ echo " [RENAMED] Documentation => $PKG_ROOT /Documentation~"
117+ fi
118+ }
119+
120+ #
121+ # @description Commit with a new version of the package and push the $PKG_BRANCH
122+ # new orphan branch (usually "upm" branch)
123+ #
124+ # @see $PKG_BRANCH
125+ # @see renameInvalidDirs()
126+ # @see fixEnvFile()
127+ commitAndPush () {
128+ # Incrementing LAST_RELEASE_TAG+1.
129+ # Keep here just to store the history, and if need this to the future/others repositories
130+ #
131+ # PS: Keep in mind that not always you would like to increment the git tag version (e.g rewriting with force an existent git tag)
132+ # [[ "$LAST_RELEASE_TAG" =~ (.*[^0-9])([0-9]+)$ ]] && LAST_RELEASE_TAG="${BASH_REMATCH[1]}$((${BASH_REMATCH[2]} + 1))";
133+
134+ local release_version=$( packageVersion " ./package.json" )
135+
136+ echo " [COMMIT AND PUSH] New version: $release_version "
137+
138+ renameInvalidDirs
139+
140+ git config --global user.name ' github-bot'
141+ git config --global user.email
' [email protected] ' 142+ git add .
143+ git commit --allow-empty -am " $COMMIT_MESSAGE "
144+
145+ echo $release_version > VERSION.md~
146+
147+ # .env (default) file path fix
148+ fixEnvFile
149+
150+ git add VERSION.md~
151+ git commit -am " fix: Samples => Samples~ and commit a new version: $release_version "
152+ git push -f -u origin " $PKG_BRANCH "
153+ }
154+
155+ # TODO: Move this function to another script file (e.g .github/scripts/local.sh)
156+ #
157+ # @description Copy a list of files and dirs from the ROOT to the package folder
158+ #
159+ # @arg $1 string A path configured as "$repository_root" local variable to be used as an origin
160+ # path to copy content into package dir
161+ # @arg $2 string A path configured as "$PKG_ROOT" environment variable to be used as
162+ # root path of the package
163+ #
164+ # @see $PKG_ROOT
165+ # @see [Exit the Bash Script if a Certain Condition Occurs](https://itslinuxfoss.com/exit-bash-script-if-certain-condition-occurs)
166+ # @see [How to Check if a File or Directory Exists in Bash](https://linuxize.com/post/bash-check-if-file-exists)
167+ copyFilesForPublish () {
168+ local repository_root=$1
169+
170+ # $PKG_ROOT environment variable check
171+ checkPkgRoot $2
172+ local pkg_root_full_path=$( realpath $PKG_ROOT )
173+
174+ if [ -z " $repository_root " ]
175+ then
176+ echo " [COPY FILES] The parameter \$ 1 => \$ repository_root is required: '$repository_root '"
177+ return 1
178+ else
179+ if [[ " $repository_root " =~ \. $ ]]
180+ then
181+ repository_root=" $repository_root /"
182+ fi
183+ fi
184+
185+ if [[ $repository_root == $pkg_root_full_path ]]
186+ then
187+ echo " [COPY FILES] Cannot copy a directory FROM: \$ repository_root => '$repository_root ' to \$ PKG_ROOT => '$pkg_root_full_path ', into itself"
188+ return 1
189+ fi
190+
191+ chmod -R 777 " $PKG_ROOT /"
192+
193+ echo " [COPY FILES] From \$ repository_root: '$( realpath $repository_root ) ', to => \$ PKG_ROOT: '$pkg_root_full_path '"
194+
195+ local files_copy=(README.md README.md.meta LICENSE LICENSE.meta Images Images.meta)
196+ for file_name in " ${files_copy[@]} "
197+ do
198+ if [[ -f " $repository_root /$file_name " && ! -f " $PKG_ROOT /$file_name " ]] || [[ -d " $repository_root /$file_name " && ! -d " $PKG_ROOT /$file_name " ]]
199+ then
200+ cp -rf " $repository_root /$file_name " " $PKG_ROOT /$file_name "
201+ echo " [COPY FILES] Copied: $PKG_ROOT /$file_name "
202+ fi
203+ done
204+ }
205+
206+ # TODO: [Feature] Use this function to loop over all packages and do all operations (copy files, rename and publish)
207+ # @see checkPkgRoot
208+ # @see [How do you store a list of directories into an array in Bash?](https://stackoverflow.com/a/4495304)
209+ fetchPackages () {
210+ local packages_root=$1
211+ checkPkgRoot
212+
213+ # PS: "<PATH>/*/" is a glob that list only directories
214+ if [ -z $packages_root ]
215+ then
216+ packages_root=(
217+ $PKG_ROOT /Packages/* /
218+ )
219+ elif [ -d $packages_root ]
220+ then
221+ packages_root=(
222+ $packages_root /* /
223+ )
224+ fi
225+
226+ for package_path in " ${packages_root[@]} "
227+ do
228+ echo " [FETCH PACKAGES] Package: '$package_path '"
229+ done
230+ }
231+
232+ # TODO: Move this function to another script file (e.g .github/scripts/local.sh)
233+ # TODO: Move common functions dependencies to another script file in order to reuse (e.g .github/scripts/common.sh)
234+ #
235+ # @description Automate all actions required before PUBLISH a package in a remote registry
236+ #
237+ # @arg $1 string A path configured as "$repository_root" local variable to be used as an origin
238+ # path to copy content into package dir
239+ # @arg $2 string A path configured as "$PKG_ROOT" environment variable to be used as
240+ # root path of the package
241+ #
242+ # @arg $3 string A flag configured as "$PUBLISH_FORCE" environment variable to force
243+ # publish from "./" root path (usually when publishing packages from a local repo)
244+ #
245+ # @see $PKG_ROOT
246+ # @see $PUBLISH_FORCE
247+ # @see renameInvalidDirs($PKG_ROOT)
248+ # @see copyFilesForPublish($1)
249+ # @see [Using Boolean Variables in Shell Scripts](https://tecadmin.net/boolean-variable-in-shell-script)
250+ localBeforePublish () {
251+ local repository_root=$1
252+ local publish_forced=' false'
253+
254+ # Check if publish "force" is true
255+ if [ -z " $PUBLISH_FORCE " ]
256+ then
257+ PUBLISH_FORCE=$3
258+ if [ -z " $PUBLISH_FORCE " ]
259+ then
260+ PUBLISH_FORCE=0
261+ fi
262+ fi
263+
264+ if [ $PUBLISH_FORCE -eq 1 ]
265+ then
266+ publish_forced=' true'
267+ fi
268+
269+ if [ -d $repository_root ] && [[ $repository_root != " ./" && $repository_root != " ." || $PUBLISH_FORCE -eq 1 ]]
270+ then
271+
272+ echo " [PUBLISH: BEFORE/PRE] Forced => '$publish_forced '"
273+
274+ # $PKG_ROOT environment variable check
275+ checkPkgRoot $2
276+
277+ renameInvalidDirs $PKG_ROOT
278+ copyFilesForPublish $repository_root
279+ else
280+ echo " [PUBLISH: BEFORE/PRE] [Skip] Bypass package preparation because \$ 1 : \$ repository_root => '$repository_root ' is invalid"
281+ fi
282+ }
283+
284+ # TODO: Move this function to another script file (e.g .github/scripts/local.sh)
285+ #
286+ # @description PUBLISH a package in a remote registry. Usually used inside of a npm script
287+ #
288+ # @arg $1 string Overrides the $PKG_ROOT environment variable with a path to a package
289+ #
290+ # @see $PKG_ROOT
291+ localPublish () {
292+ # $PKG_ROOT environment variable check
293+ checkPkgRoot $1
294+
295+ cd $PKG_ROOT
296+ npm run package:prepare && npm publish
297+ }
298+
299+ run () {
300+ if [ $1 == " push" ]
301+ then
302+ commitAndPush
303+ elif [ $1 == " movePackagesFolder" ]
304+ then
305+ copyPackagesContent
306+ elif [ $1 == " githubActionsVariables" ]
307+ then
308+ githubActionsOutputs
309+ elif [ $1 == " fetchPackages" ]
310+ then
311+ fetchPackages $2
312+ elif [ $1 == " copyFilesForPublish" ]
313+ then
314+ copyFilesForPublish $2 $3
315+ elif [ $1 == " fixEnvFile" ]
316+ then
317+ fixEnvFile $2
318+ elif [ $1 == " renameInvalidDirs" ]
319+ then
320+ renameInvalidDirs $2
321+ elif [ $1 == " localBeforePublish" ]
322+ then
323+ localBeforePublish $2
324+ elif [ $1 == " localPublish" ]
325+ then
326+ localPublish $2
327+ else
328+ echo " [ERROR] INVALID SCRIPT OPERATION"
329+ exit 1
330+ fi
331+ }
332+
333+ run $1 $2 $3
0 commit comments