@@ -16,17 +16,14 @@ description: |
1616 build artifact file that contains the same.
1717
1818 This action assumes it is working with a Semantic Versioning version
19- number. The form of the final, full version number is
20- <branch invariant version>.<build number>-<build variant>
21-
19+ number.
20+
2221 References:
2322 https://semver.org/
2423 https://packaging.python.org/en/latest/specifications/version-specifiers/
24+ https://peps.python.org/pep-0440/
2525
26- # TODO: Detect branch for consideration of constructing a build_variant automatically?
27- # Unless we have a strict branching/release policy, this may never be possible.
2826# TODO: add support for epochs (e.g. "<epoch>!" prefix)
29- # TODO: add support for local variants (e.g. "+<local variant>" suffix)
3027# TODO: Can/should we *also* encode the SHA? While I dislike its lack of sequence
3128# or uniqueness, it *does* encode useful information.
3229
@@ -58,35 +55,83 @@ runs:
5855 using : " composite"
5956 steps :
6057 - id : generate-version-with-buildnum
58+ # This was initially developed to be a generic semver build number
59+ # generator. PEP 440 has some quirks in regard to the semver specification:
60+ # - PEP 440 specifies variant suffixes of the form "b#" over "-beta[.#]"
61+ # In practice, this makes it harder to promote the build number as part of
62+ # the version that appears before the pre-release suffix.
63+ # - PEP 440 expects single letter variants "a", "b", "rc" over
64+ # the textual "alpha", "beta", "rc" identifiers, and only
65+ # expects these defined pre-release variants. Other variants
66+ # do not seem to be well-supported by python tooling.
67+ # - PEP 440 treats development releases as different from the variant,
68+ # rather than being a pre-release variant of pre-alpha maturity.
69+ # Fully handling this would be more complex.
6170 name : " Prepare build version file"
6271 shell : bash
6372 run : |
64- # Should be closely synonymous with SCM branch
65- version_invariant=$(head -1 version.txt | tr -d '\n')
66-
67- # "pre-release" in semver
68- if [ "${{ inputs.build-variant }}" = "release" ]
69- then
70- version_variant=""
71- else
72- version_variant=${{ inputs.build-variant }}
73- fi
74-
7573 # Generated build number
7674 build_timestamp_b10=$(date +%s) # Time based build number - Base 10
7775 build_timestamp_b16=$(printf '%x' ${build_timestamp_b10}) # Time based build number - Base 16 - More compact, but might be interpreted as a non-digit
7876 build_timestamp_bx16=$(printf '0x%x' ${build_timestamp_b10}) # As above, with leading '0x' so it's never not seen as hex (but is less compact)
79- # Python packaging doesn't like the "x" in the build number build numbers (even though it makes it less ambigious)
80- # Reverting to base 10 for now. *sigh*
81- version_buildnum=${build_timestamp_b10}
77+ semver_buildnum=${build_timestamp_b10}
78+
79+ # The invariant portion of the version should be closely
80+ # synonymous with SCM branch
81+ version_invariant=$(head -1 version.txt | tr -d '\n')
82+
83+ # Configure the pre-release variant for the semver
84+ semver_variant=${{ inputs.build-variant }}
85+ case "${{ inputs.build-variant }}" in
86+ dev)
87+ # PEP 440 treats "dev" as a different dimmension than the variant.
88+ # Squashing to alpha to reduce dimmensions we use.
89+ semver_variant_py="a"
90+ semver_buildnum_py="${semver_buildnum}"
91+ ;;
92+ alpha)
93+ semver_variant_py="a"
94+ semver_buildnum_py="${semver_buildnum}"
95+ ;;
96+ beta)
97+ semver_variant_py="b"
98+ semver_buildnum_py="${semver_buildnum}"
99+ ;;
100+ rc)
101+ semver_variant_py="rc"
102+ semver_buildnum_py="${semver_buildnum}"
103+ ;;
104+ release)
105+ semver_variant_py=""
106+ # PEP 440 specifies "+<build>" for local variants,
107+ # making it harder to use it for a public release build number.
108+ semver_buildnum_py=""
109+ ;;
110+ *)
111+ echo "Unknown build variant: ${{ inputs.build-variant }}"
112+ exit 1
113+ ;;
114+ esac
82115
83116 # Putting it all together
84- printf "${version_invariant}.${version_buildnum}${version_variant:+-}${version_variant}" > version-with-buildnum.txt
117+
118+ # Semver variant 1:
119+ # <version>.<buildnum>-<variant>
120+ # printf "${version_invariant}.${semver_buildnum}${semver_variant:+-}${semver_variant}" > version-with-buildnum.txt
121+
122+ # Semver variant 2:
123+ # <version>-<variant>+<buildnum>
124+ # printf "${version_invariant}${semver_variant:+-}${semver_variant}${semver_buildnum:++}${semver_buildnum}" > version-with-buildnum.txt
125+
126+ # PEP 440 semver variant:
127+ printf "${version_invariant}${semver_variant_py}${semver_buildnum_py}" > version-with-buildnum.txt
128+
129+ # Saving the result as an artifact
85130 echo "Created version-with-buildnum.txt : $(cat version-with-buildnum.txt)"
86131 echo "version-with-buildnum=$(cat version-with-buildnum.txt)" | tee -a $GITHUB_OUTPUT
87132 echo "version=$(cat version.txt)" | tee -a $GITHUB_OUTPUT
88- echo "buildnum=${version_buildnum }" | tee -a $GITHUB_OUTPUT
89- echo "variant-normal=${version_variant }" | tee -a $GITHUB_OUTPUT
133+ echo "buildnum=${semver_buildnum }" | tee -a $GITHUB_OUTPUT
134+ echo "variant-normal=${semver_variant }" | tee -a $GITHUB_OUTPUT
90135 echo "variant-raw=${{ inputs.build-variant }}" | tee -a $GITHUB_OUTPUT
91136 - name : Save Artifacts - version-with-buildnum.txt
92137 uses : actions/upload-artifact@v4
0 commit comments