diff --git a/.github/workflows/auto-git-release-production.yml b/.github/workflows/auto-git-release-production.yml index 102fd547..be79473a 100644 --- a/.github/workflows/auto-git-release-production.yml +++ b/.github/workflows/auto-git-release-production.yml @@ -1,8 +1,10 @@ # Summary: # Automatically tag and release when changes land on the "main" branch. +# It uses "semantic-version" to resolve the next version to use, and then we use GitHub CLI to create or update the releases. # # See https://github.com/PaulHatch/semantic-version https://github.com/PaulHatch/semantic-version/tree/v5.0.2 # See https://github.com/softprops/action-gh-release https://github.com/softprops/action-gh-release/tree/v1 +# See https://github.com/Actions-R-Us/actions-tagger https://github.com/Actions-R-Us/actions-tagger/releases/tag/v2.0.3 name: 'Auto release' on: @@ -49,34 +51,71 @@ jobs: echo "current_commit: ${{steps.next_semantic_version.outputs.current_commit}}" - name: Creating Git release tag for the "${{steps.next_semantic_version.outputs.version_tag}}" version - uses: softprops/action-gh-release@v1 - with: # See https://github.com/softprops/action-gh-release#-customizing - token: "${{ secrets.GITHUB_TOKEN }}" - tag_name: ${{steps.next_semantic_version.outputs.version_tag}} - name: "Automatic release ${{steps.next_semantic_version.outputs.version_tag}}" - prerelease: false - generate_release_notes: true - files: | - CHANGELOG.md + run: | + gh release create ${{steps.next_semantic_version.outputs.version_tag}} \ + --title "${{steps.next_semantic_version.outputs.version_tag}}" \ + --latest \ + --generate-notes \ + --target $GITHUB_SHA + env: + GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + + # Check if the major version already exists (if it doesn't, we'll create it - if it does, we'll update it) + - name: Check if tag "v${{steps.next_semantic_version.outputs.major}}" exists + uses: mukunku/tag-exists-action@v1.2.0 + id: majorTagExists + with: # See https://github.com/mukunku/tag-exists-action#inputs + tag: "v${{steps.next_semantic_version.outputs.major}}" + + - run: "echo \"Check if majorTagExists: ${{ steps.majorTagExists.outputs.exists }}\"" - - name: Updating Git release tag for "latest" version - uses: softprops/action-gh-release@v1 - with: # See https://github.com/softprops/action-gh-release#-customizing - token: "${{ secrets.GITHUB_TOKEN }}" - tag_name: latest - name: "Latest release (auto-update) - UNSAFE for production usage" - prerelease: false - generate_release_notes: true - files: | - CHANGELOG.md + # See https://cli.github.com/manual/gh_release_create + - name: Creating new release for the major "v${{steps.next_semantic_version.outputs.major}}" version + if: ${{ steps.majorTagExists.outputs.exists == 'false' }} + run: | + gh release create v${{steps.next_semantic_version.outputs.major}} \ + --title "v${{steps.next_semantic_version.outputs.major}} MAJOR release (auto-updated)" \ + --generate-notes \ + --target $GITHUB_SHA + env: + GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + + # See https://cli.github.com/manual/gh_release_edit + - name: Updating existing release for the major "v${{steps.next_semantic_version.outputs.major}}" version + if: ${{ steps.majorTagExists.outputs.exists == 'true' }} + run: | + gh release edit v${{steps.next_semantic_version.outputs.major}} \ + --title "v${{steps.next_semantic_version.outputs.major}} MAJOR release (auto-updated)" \ + --target $GITHUB_SHA + env: + GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - - name: Updating Git release tag for the major "v${{steps.next_semantic_version.outputs.major}}" version - uses: softprops/action-gh-release@v1 - with: # See https://github.com/softprops/action-gh-release#-customizing - token: "${{ secrets.GITHUB_TOKEN }}" - tag_name: "v${{steps.next_semantic_version.outputs.major}}" - name: "v${{steps.next_semantic_version.outputs.major}} latest release (auto-update)" - prerelease: false - generate_release_notes: true - files: | - CHANGELOG.md + # Check if the minor version already exists (if it doesn't, we'll create it - if it does, we'll update it) + - name: Check if tag "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}" exists + uses: mukunku/tag-exists-action@v1.2.0 + id: minorTagExists + with: # See https://github.com/mukunku/tag-exists-action#inputs + tag: "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}" + + - run: "echo \"Check if minorTagExists: ${{ steps.minorTagExists.outputs.exists }}\"" + + # See https://cli.github.com/manual/gh_release_create + - name: Creating new release for the minor "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}" version + if: ${{ steps.minorTagExists.outputs.exists == 'false' }} + run: | + gh release create v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}} \ + --title "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}} MINOR release (auto-updated)" \ + --generate-notes \ + --target $GITHUB_SHA + env: + GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + + # See https://cli.github.com/manual/gh_release_edit + - name: Updating existing release for the minor "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}" version + if: ${{ steps.minorTagExists.outputs.exists == 'true' }} + run: | + gh release edit v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}} \ + --title "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}} MINOR release (auto-updated)" \ + --target $GITHUB_SHA + env: + GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/auto-git-release-staging.yml b/.github/workflows/auto-git-release-staging.yml index 6a8fe51c..f07f1d26 100644 --- a/.github/workflows/auto-git-release-staging.yml +++ b/.github/workflows/auto-git-release-staging.yml @@ -1,5 +1,6 @@ # Summary: # Automatically tag and release when changes land on the "main" branch. +# It uses "semantic-version" to resolve the next version to use, and then we use GitHub CLI to create or update the releases. # # See https://github.com/PaulHatch/semantic-version https://github.com/PaulHatch/semantic-version/tree/v5.0.2 # See https://github.com/softprops/action-gh-release https://github.com/softprops/action-gh-release/tree/v1 @@ -47,35 +48,66 @@ jobs: echo "previous_commit: ${{steps.next_semantic_version.outputs.previous_commit}}" echo "current_commit: ${{steps.next_semantic_version.outputs.current_commit}}" - - name: Creating Git release tag for the "v${{steps.next_semantic_version.outputs.version}}" version - uses: softprops/action-gh-release@v1 - with: # See https://github.com/softprops/action-gh-release#-customizing - token: "${{ secrets.GITHUB_TOKEN }}" - tag_name: "v${{steps.next_semantic_version.outputs.version}}" - name: "Automatic release v${{steps.next_semantic_version.outputs.version}}" - prerelease: true - generate_release_notes: true - files: | - CHANGELOG.md + # Check if the major version already exists (if it doesn't, we'll create it - if it does, we'll update it) + - name: Check if tag "v${{steps.next_semantic_version.outputs.major}}-rc" exists + uses: mukunku/tag-exists-action@v1.2.0 + id: majorTagExists + with: # See https://github.com/mukunku/tag-exists-action#inputs + tag: "v${{steps.next_semantic_version.outputs.major}}-rc" - - name: Updating Git release tag for "latest-rc" version - uses: softprops/action-gh-release@v1 - with: # See https://github.com/softprops/action-gh-release#-customizing - token: "${{ secrets.GITHUB_TOKEN }}" - tag_name: latest-rc - name: "Latest release (auto-update) - UNSAFE for production usage" - prerelease: true - generate_release_notes: true - files: | - CHANGELOG.md + - run: "echo \"Check if majorTagExists: ${{ steps.majorTagExists.outputs.exists }}\"" - - name: Updating Git release tag for the major "v${{steps.next_semantic_version.outputs.major}}-rc" version - uses: softprops/action-gh-release@v1 - with: # See https://github.com/softprops/action-gh-release#-customizing - token: "${{ secrets.GITHUB_TOKEN }}" - tag_name: "v${{steps.next_semantic_version.outputs.major}}-rc" - name: "v${{steps.next_semantic_version.outputs.major}}-rc latest release (auto-update)" - prerelease: true - generate_release_notes: true - files: | - CHANGELOG.md + # See https://cli.github.com/manual/gh_release_create + - name: Creating new release for the major "v${{steps.next_semantic_version.outputs.major}}-rc" version + if: ${{ steps.majorTagExists.outputs.exists == 'false' }} + run: | + gh release create v${{steps.next_semantic_version.outputs.major}}-rc \ + --title "v${{steps.next_semantic_version.outputs.major}}-rc MAJOR release (auto-updated)" \ + --generate-notes \ + --prerelease \ + --target $GITHUB_SHA + env: + GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + + # See https://cli.github.com/manual/gh_release_edit + - name: Updating existing release for the major "v${{steps.next_semantic_version.outputs.major}}-rc" version + if: ${{ steps.majorTagExists.outputs.exists == 'true' }} + run: | + gh release edit v${{steps.next_semantic_version.outputs.major}}-rc \ + --title "v${{steps.next_semantic_version.outputs.major}}-rc MAJOR release (auto-updated)" \ + --prerelease \ + --target $GITHUB_SHA + env: + GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + + # Check if the minor version already exists (if it doesn't, we'll create it - if it does, we'll update it) + - name: Check if tag "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc" exists + uses: mukunku/tag-exists-action@v1.2.0 + id: minorTagExists + with: # See https://github.com/mukunku/tag-exists-action#inputs + tag: "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc" + + - run: "echo \"Check if minorTagExists: ${{ steps.minorTagExists.outputs.exists }}\"" + + # See https://cli.github.com/manual/gh_release_create + - name: Creating new release for the minor "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc" version + if: ${{ steps.minorTagExists.outputs.exists == 'false' }} + run: | + gh release create v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc \ + --title "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc MINOR release (auto-updated)" \ + --generate-notes \ + --prerelease \ + --target $GITHUB_SHA + env: + GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + + # See https://cli.github.com/manual/gh_release_edit + - name: Updating existing release for the minor "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc" version + if: ${{ steps.minorTagExists.outputs.exists == 'true' }} + run: | + gh release edit v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc \ + --title "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc MINOR release (auto-updated)" \ + --prerelease \ + --target $GITHUB_SHA + env: + GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/auto-tag-on-release.yml b/.github/workflows/auto-tag-on-release.yml deleted file mode 100644 index 66eeec5f..00000000 --- a/.github/workflows/auto-tag-on-release.yml +++ /dev/null @@ -1,22 +0,0 @@ -# Summary: -# Upon MANUAL release, automatically update the MAJOR tag to make it point to the latest version of any minor/patch release, for easy use by the consumers. -# Also updates the "latest" tag automatically (auto-created), which is meant to be used for development/testing only, not for production. -# This way, consumers can use @v1 and the @v1 is a tag that is automatically updated when you release a new v1 minor/patch version. -# Note that if you release a "pre-release", it won't automatically update the "latest" tag, nor the MAJOR tag. -# -# See https://github.com/Actions-R-Us/actions-tagger https://github.com/Actions-R-Us/actions-tagger/releases/tag/v2.0.3 - -name: 'Auto-tag upon release' -on: - release: - types: [published, edited] - -jobs: - actions-tagger: - runs-on: ubuntu-22.04 - steps: - - uses: Actions-R-Us/actions-tagger@v2.0.3 - env: - GITHUB_TOKEN: "${{ github.token }}" - with: - publish_latest_tag: true diff --git a/README.md b/README.md index e83a3f84..4d75335e 100644 --- a/README.md +++ b/README.md @@ -190,43 +190,58 @@ Then, you'll need to create and add your own Vercel token there (`VERCEL_TOKEN`) We follow Semantic Versioning. (`major.minor.patch`) -Our versioning process is completely automated, any changes landing on the `main` branch will trigger a new [release](../../releases). - -- `MAJOR`: Behavioral change of the existing API that would result in a breaking change. - - E.g: Removing an input, or changing the output would result in a breaking change and thus would be released as a new MAJOR version. -- `Minor`: Behavioral change of the existing API that would **not** result in a breaking change. - - E.g: Adding an optional input would result in a non-breaking change and thus would be released as a new Minor version. +Our versioning process is completely automated, any changes landing on the `main` branch will trigger a +new [release](../../releases). + +- `(MAJOR)`: Behavioral change of the existing API that would result in a breaking change. + - E.g: Removing an input, or changing the output would result in a breaking change and thus would be released as a + new MAJOR version. +- `(MINOR)`: Behavioral change of the existing API that would **not** result in a breaking change. + - E.g: Adding an optional input would result in a non-breaking change and thus would be released as a new MINOR + version. - `Patch`: Any other change. - - E.g: Documentation, tests, refactoring, bug fix, etc. + - E.g: Documentation, tests, refactoring, bug fix, etc. ## Releases versions: The examples above use an auto-updated major version tag (`@v1`). -It is also possible to use the `@latest` and `@latest-rc` tags. (RC stands for "Release candidate", which is similar to a Beta version) +It is also possible to use the `@latest` tag. (RC stands for "Release candidate", which is similar to a Beta version) -While those options can be useful, we intend to give some "production-grade" best practices. +While those options can be useful, we intend to give some "production-grade" best practices. -- **Do NOT use `@latest` for production**, ever. While only "supposed-to-be-stable" versions will be tagged as `@latest`, it could harbor bugs nonetheless. -- You can use auto-upgrading major version, such as `@v1`, but this is not a best practice, see our explanations below. +- **Do NOT use `@latest` for production**, ever. While only "supposed-to-be-stable" versions will be tagged + as `@latest`, it could harbor bugs nonetheless. +- You can use auto-upgrading major version, such as `@v1` or `@v1.2`, but this is not always the best practice, see our + explanations below. -### Special tags and production-grade apps best practices +### Special tags and best practices for production-grade apps -Here are a few useful options you can use to pin a more-or-less specific version of our GitHub Action, alongside some "production-grade" best practices. +Here are a few useful options you can use to pin a more-or-less specific version of our GitHub Action, alongside some " +production-grade" best practices. -- `@{COMMIT-SHA}`, e.g: `@1271dc3fc4c4c8bc62ba5a4e248dac95cb82d0e3`, recommended for all production-grade apps, it's the only truly safe way to pinpoint a version that cannot change against your will (**SAFEST**) -- `@{MAJOR}-{MINOR}-{PATCH}`, e.g: `@v1.2.31`, while not as safe as the `COMMIT-SHA` way, it's what most people use (SAFER) +- `@{COMMIT-SHA}`, e.g: `@1271dc3fc4c4c8bc62ba5a4e248dac95cb82d0e3`, recommended for all production-grade apps, it's the + only truly safe way to pinpoint a version that cannot change against your will (**SAFEST**) +- `@{MAJOR}-{MINOR}-{PATCH}`, e.g: `@v1.2.31`, while not as safe as the `COMMIT-SHA` way, it's what most people use ( + SAFER) - `@{MAJOR}`, e.g: `@v1`, can be used on production, but we do not advise to do so (SAFE-ISH) -- `@{MAJOR}-rc`, e.g: `@v1-rc`, **reserved for development mode**, useful when debugging on a specific prerelease version (UNSAFE) +- `@{MAJOR}-rc`, e.g: `@v1-rc`, **reserved for development mode**, useful when debugging on a specific prerelease + version (UNSAFE) +- `@{MAJOR}.{MINOR}`, e.g: `@v1.2`, can be used on production, but we do not advise to do so (SAFE-ISH) +- `@{MAJOR}.{MINOR}-rc`, e.g: `@v1.2-rc`, **reserved for development mode**, useful when debugging on a specific + prerelease + version (UNSAFE) - `@latest`, **reserved for development mode**, useful when debugging (UNSAFE) -- `@latest-rc`, **reserved for development mode**, useful when debugging on prerelease versions (UNSAFE) **"But, what is the issue with the `@{MAJOR}-{MINOR}-{PATCH}` way to pin a specific version"?** -> Well, if this repository gets hacked by a 3rd party, **they can easily change all Git tags to a different commit**, which could contain malicious code. +> Well, if this repository gets hacked by a 3rd party, **they can easily change all Git tags to a different commit**, +which could contain malicious code. -That's why **pinning a specific commit SHA is the only truly safe option**. This way, the code you're using **cannot be changed against your will**. +That's why **pinning a specific commit SHA is the only truly safe option**. This way, the code you're using **cannot be +changed against your will**. -Most people won't care about this and will use a MAJOR version tag instead anyway, such as `@v1`. It's common, but not the best practice. +Most people won't care about this and will use a MAJOR version tag instead anyway, such as `@v1`. It's common, but not +often the best practice. It all comes down to the risks you're ready to take, and it's up to you to decide what's best in your situation.