diff --git a/.gitignore b/.gitignore
index 531374f..7b7b8bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -204,3 +204,7 @@ PHP-Parser*/
src/*.so
src/*.dylib
src/*.dll
+
+# ignoring output of package.xml as it needs to be generated from ./prepare_release.sh in each publishing
+package.xml
+*.tgz
diff --git a/package.xml-template_post b/package.xml-template_post
new file mode 100644
index 0000000..2506f9d
--- /dev/null
+++ b/package.xml-template_post
@@ -0,0 +1,19 @@
+
+
+
+
+ 7.4.0
+
+
+ 1.10.0
+
+
+
+awscrt
+
+
+
+
+
+
+
diff --git a/package.xml-template_pre b/package.xml-template_pre
new file mode 100644
index 0000000..53c7d5b
--- /dev/null
+++ b/package.xml-template_pre
@@ -0,0 +1,24 @@
+
+
+ awscrt
+ pecl.php.net
+ AWS Common Runtime PHP bindings
+ AWS Common Runtime provides a set of low level tools as network protocols and authentication used by the AWSSDK for PHP to provide high level API to access AWS services.
+
+ {{{NAME}}}
+ {{{USER}}}
+ {{{EMAIL}}}
+ yes
+
+ {{{TODAY}}}
+
+ {{{VERSION}}}
+ 1.0.0
+
+
+ devel
+ stable
+
+ Apache License Version 2.0
+ {{{NOTES}}}
+
diff --git a/prepare_package_xml.sh b/prepare_package_xml.sh
new file mode 100755
index 0000000..9e77582
--- /dev/null
+++ b/prepare_package_xml.sh
@@ -0,0 +1,144 @@
+#!/bin/zsh
+zparseopts -A opts -name: -user: -email: -version: -notes:
+if [[ $# -lt 10 ]]
+then
+ echo "Usage ${0} --name NAME, --user USER --email EMAIL --version VERSION --notes NOTES"
+ exit 1
+fi
+NAME="${opts[--name]}"
+USER="${opts[--user]}"
+EMAIL="${opts[--email]}"
+VERSION="${opts[--version]}"
+NOTES="${opts[--notes]}"
+
+TODAY=$(date -u +%Y-%m-%d)
+
+cat package.xml-template_pre \
+ | sed "s/{{{NAME}}}/$NAME/g" \
+ | sed "s/{{{USER}}}/$USER/g" \
+ | sed "s/{{{EMAIL}}}/$EMAIL/g" \
+ | sed "s/{{{TODAY}}}/$TODAY/g" \
+ | sed "s/{{{VERSION}}}/$VERSION/g" \
+ | sed "s/{{{NOTES}}}/$NOTES/g"
+
+source_ext='(c|cc|h|cpp|hpp|m4|w32|ini|frag|cmake|inl|in|py|gnu|yaml|def|pl|S|s|errordata|go|lds|num|asm|mod|peg|mk|rs|toml|sh)'
+doc_ext='(md|json|html|dot|graphml|png|gn|sha1|css|rst|)'
+
+special_docs='(LICENSE*|NOTICE|changelog.txt|CHANGELOG|THIRD-PARTY|README*|readme|METADATA|CONTRIBUTORS|UPDATING|doc.config)'
+special_tests='(ci-test.sh|format-check.sh|run_tests*|sanitizer-blacklist.txt|run-clang-tidy.sh|benchmark-build-run.sh|break-tests.sh|generate-coverage.sh|test.xml)'
+special_src='(gen_api.php|gen_stub.php|CMakeLists.txt|post.sh|postun.sh|Makefile*|build-buildspec.sh|build-deps.sh|objects.txt|go.*|BUILD*|DEPS|install_and_run.sh|codemod.sh|requirements.txt)'
+skip_files='(package.xml*|prepare_release.sh|codereview.settings|*.o|*.a|*.obj|*.lib|break-tests-android.sh|whitespace.txt|prepare_package_xml.sh|crypto_test_data.cc|*.pdf|*.svg|*.docx|cbmc-proof.txt|codecov*|litani*|*.toml)'
+
+special_scripts='(awscrt.stub.php)'
+
+skip_directories='(tests|test|AWSCRTAndroidTestRunner|docker-images|codebuild|fuzz|verfication|third_party|docs|generated-src|aws-lc|aws-crt-sys)'
+
+process_file() {
+ if (( $# == 0 ))
+ then
+ echo "ERROR: filename not passed"
+ exit 1
+ fi
+ if [[ $1 = $~skip_files ]]
+ then
+ # This file is not part of the release bundle
+ return 0
+ fi
+
+ echo -n ''
+ return 0
+}
+
+
+process_dir() {
+ if (( $# == 0 ))
+ then
+ echo "WARNING: dirname not passed"
+ exit 1
+ fi
+ if [[ "${1}" = $~skip_directories ]]
+ then
+ return 0
+ fi
+ echo ''
+ cd "$1"
+ for a in *
+ do
+ if [[ -f ${a} ]]
+ then process_file "${a}"
+ else process_dir "${a}"
+ fi
+ done
+ # Special cases for compiler features placed in tests directories in and s2n
+ if [[ "${1}" = "s2n" && -d tests ]]
+ then
+ echo ''
+ echo ''
+ cd tests/features
+ for a in *
+ do
+ process_file "${a}"
+ done
+ cd ../..
+ echo ''
+ echo ''
+ fi
+ echo ''
+ cd ..
+ return 0
+}
+
+echo ''
+for a in *
+do
+ if [[ ${a} == 'tests' ]]
+ then
+ echo ''
+ for b in tests/*
+ do
+ echo ''
+ done
+ echo ''
+ continue
+ fi
+ if [[ -f ${a} ]]
+ then process_file "${a}"
+ else process_dir "${a}"
+ fi
+done
+echo ''
+
+cat package.xml-template_post
+
diff --git a/prepare_release.sh b/prepare_release.sh
new file mode 100755
index 0000000..3a9c5f4
--- /dev/null
+++ b/prepare_release.sh
@@ -0,0 +1,31 @@
+#!/bin/zsh
+zparseopts -A opts -name: -user: -email: -version: -notes:
+if [[ $# -lt 10 ]]; then
+ echo "Usage ${0} --name NAME --user USER --email EMAIL --version VERSION --notes NOTES"
+ exit 1
+fi
+PACKAGE='awscrt'
+NAME="${opts[--name]}"
+USER="${opts[--user]}"
+EMAIL="${opts[--email]}"
+VERSION="${opts[--version]}"
+NOTES="${opts[--notes]}"
+
+./prepare_package_xml.sh --name "${NAME}" --user "${USER}" --email "${EMAIL}" --version "${VERSION}" --notes "${NOTES}" >package.xml
+if [[ $? -ne 0 ]]; then
+ echo "ERROR PROCESSING review package.xml"
+ exit 1
+fi
+tidy -xml -m -i package.xml
+pear package-validate
+if [[ $? -ne 0 ]]; then
+ echo "ERROR VALIDATING review package.xml"
+ exit 1
+fi
+pear package
+if [[ $? -ne 0 ]]; then
+ echo "ERROR PROCESSING review package.xml"
+ exit 1
+fi
+
+echo "Size of ${PACKAGE}-${VERSION}.tgz: " $(du -h "${PACKAGE}-${VERSION}.tgz")