-
Notifications
You must be signed in to change notification settings - Fork 1
feanil/setup semantic release #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,93 @@ | ||||||||||||
| name: Python Semantic Release | ||||||||||||
|
|
||||||||||||
| on: | ||||||||||||
| push: | ||||||||||||
| branches: [main] | ||||||||||||
|
|
||||||||||||
| jobs: | ||||||||||||
| run_tests: | ||||||||||||
| uses: ./.github/workflows/ci.yml | ||||||||||||
|
|
||||||||||||
| release: | ||||||||||||
| needs: run_tests | ||||||||||||
| runs-on: ubuntu-latest | ||||||||||||
| if: github.ref_name == 'main' | ||||||||||||
| concurrency: | ||||||||||||
| group: ${{ github.workflow }}-release-${{ github.ref_name }} | ||||||||||||
| cancel-in-progress: false | ||||||||||||
|
|
||||||||||||
| permissions: | ||||||||||||
| contents: write | ||||||||||||
|
|
||||||||||||
| steps: | ||||||||||||
| # Note: We checkout the repository at the branch that triggered the workflow. | ||||||||||||
| # Python Semantic Release will automatically convert shallow clones to full clones | ||||||||||||
| # if needed to ensure proper history evaluation. However, we forcefully reset the | ||||||||||||
| # branch to the workflow sha because it is possible that the branch was updated | ||||||||||||
| # while the workflow was running, which prevents accidentally releasing un-evaluated | ||||||||||||
| # changes. | ||||||||||||
| - name: Setup | Checkout Repository on Release Branch | ||||||||||||
| uses: actions/checkout@v4 | ||||||||||||
| with: | ||||||||||||
| ref: ${{ github.ref_name }} | ||||||||||||
|
|
||||||||||||
| - name: Setup | Force release branch to be at workflow sha | ||||||||||||
| run: | | ||||||||||||
| git reset --hard ${{ github.sha }} | ||||||||||||
| - name: Action | Semantic Version Release | ||||||||||||
| id: release | ||||||||||||
| # Adjust tag with desired version if applicable. | ||||||||||||
| uses: python-semantic-release/[email protected] | ||||||||||||
| with: | ||||||||||||
| github_token: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||
| git_committer_name: "github-actions" | ||||||||||||
| git_committer_email: "[email protected]" | ||||||||||||
| working-directory: './backend' | ||||||||||||
|
Comment on lines
+38
to
+46
|
||||||||||||
|
|
||||||||||||
| - name: Publish | Upload to GitHub Release Assets | ||||||||||||
| uses: python-semantic-release/[email protected] | ||||||||||||
| if: steps.release.outputs.released == 'true' | ||||||||||||
| with: | ||||||||||||
| github_token: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||
| tag: ${{ steps.release.outputs.tag }} | ||||||||||||
| working-directory: './backend' | ||||||||||||
|
Comment on lines
+48
to
+54
|
||||||||||||
|
|
||||||||||||
| - name: Upload | Distribution Artifacts | ||||||||||||
| uses: actions/upload-artifact@v4 | ||||||||||||
| with: | ||||||||||||
| name: distribution-artifacts | ||||||||||||
| path: dist | ||||||||||||
feanil marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
| if-no-files-found: error | ||||||||||||
| working-directory: './backend' | ||||||||||||
|
Comment on lines
+60
to
+62
|
||||||||||||
| path: dist | |
| if-no-files-found: error | |
| working-directory: './backend' | |
| path: backend/dist | |
| if-no-files-found: error |
feanil marked this conversation as resolved.
Show resolved
Hide resolved
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pypa/gh-action-pypi-publish action is being used with deprecated parameters. The 'user' and 'password' parameters are deprecated in favor of trusted publishing. Since the job already has 'id-token: write' permission configured (line 75), which is required for trusted publishing, the 'user' and 'password' parameters should be removed to use the more secure OIDC-based trusted publisher flow instead of API tokens.
| user: __token__ | |
| password: ${{ secrets.PYPI_UPLOAD_TOKEN }} |
Copilot
AI
Jan 2, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using username/password authentication with PyPI is deprecated. The workflow is using user: __token__ and password parameters, but with the id-token: write permission already granted, you should use trusted publishing instead. Remove the user and password parameters to use OIDC trusted publishing, which is more secure and doesn't require storing secrets.
| user: __token__ | |
| password: ${{ secrets.PYPI_UPLOAD_TOKEN }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,28 +18,13 @@ | |
| from subprocess import check_call | ||
|
|
||
| from django import setup as django_setup | ||
|
|
||
|
|
||
| def get_version(*file_paths): | ||
| """ | ||
| Extract the version string from the file. | ||
| Input: | ||
| - file_paths: relative path fragments to file with | ||
| version string | ||
| """ | ||
| filename = os.path.join(os.path.dirname(__file__), *file_paths) | ||
| version_file = open(filename, encoding="utf8").read() | ||
| version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", version_file, re.M) | ||
| if version_match: | ||
| return version_match.group(1) | ||
| raise RuntimeError('Unable to find version string.') | ||
| from importlib.metadata import version as get_version | ||
|
|
||
|
|
||
| REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | ||
| sys.path.append(REPO_ROOT) | ||
|
|
||
| VERSION = get_version('../sample_plugin', '__init__.py') | ||
| VERSION = get_version('openedx-sample-plugin') | ||
|
Comment on lines
+21
to
+27
|
||
| # Configure Django for autodoc usage | ||
| os.environ['DJANGO_SETTINGS_MODULE'] = 'test_settings' | ||
| django_setup() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ name = "openedx-sample-plugin" | |
| description = "A sample backend plugin for the Open edX Platform" | ||
| requires-python = ">=3.11" | ||
| license="Apache-2.0" | ||
| version = "0.1.0" | ||
|
||
| authors = [ | ||
| {name = "Open edX Project", email = "[email protected]"}, | ||
| ] | ||
|
|
@@ -24,7 +25,7 @@ keywords= [ | |
| "edx", | ||
| ] | ||
|
|
||
| dynamic = ["version", "readme", "dependencies"] | ||
| dynamic = ["readme", "dependencies"] | ||
|
|
||
| [project.entry-points."lms.djangoapp"] | ||
| sample_plugin = "sample_plugin.apps:SamplePluginConfig" | ||
|
|
@@ -37,10 +38,12 @@ Homepage = "https://openedx.org/openedx/sample-plugin" | |
| Repository = "https://openedx.org/openedx/sample-plugin" | ||
|
|
||
| [tool.setuptools.dynamic] | ||
| version = {attr = "sample_plugin.__version__"} | ||
| readme = {file = ["README.rst", "CHANGELOG.rst"]} | ||
| dependencies = {file = "requirements/base.in"} | ||
|
|
||
| [tool.setuptools.packages.find] | ||
| include = ["sample_plugin*"] | ||
| exclude = ["sample_plugin.tests*"] | ||
|
|
||
| [tool.semantic_release.changelog.default_templates] | ||
| changelog_file = "../CHANGELOG.md" | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,4 +2,8 @@ | |||||||||||||||||||||||||||
| A sample backend plugin for the Open edX Platform. | ||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| __version__ = "0.1.0" | ||||||||||||||||||||||||||||
| from importlib.metadata import version as get_version | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| # The name of the package is `openedx-sample-plugin` but __package__ is `sample_plugin` so we hardcode the name of the | ||||||||||||||||||||||||||||
| # package here so that the version fetching works correctly. A lot of examples will show using `__package__`. | ||||||||||||||||||||||||||||
| __version__ = get_version('openedx-sample-plugin') | ||||||||||||||||||||||||||||
|
Comment on lines
+5
to
+9
|
||||||||||||||||||||||||||||
| from importlib.metadata import version as get_version | |
| # The name of the package is `openedx-sample-plugin` but __package__ is `sample_plugin` so we hardcode the name of the | |
| # package here so that the version fetching works correctly. A lot of examples will show using `__package__`. | |
| __version__ = get_version('openedx-sample-plugin') | |
| from importlib.metadata import PackageNotFoundError, version as get_version | |
| # The name of the package is `openedx-sample-plugin` but __package__ is `sample_plugin` so we hardcode the name of the | |
| # package here so that the version fetching works correctly. A lot of examples will show using `__package__`. | |
| try: | |
| __version__ = get_version('openedx-sample-plugin') | |
| except PackageNotFoundError: | |
| __version__ = "0.0.0" |
Uh oh!
There was an error while loading. Please reload this page.