-
Couldn't load subscription status.
- Fork 8
Add GitHub workflow files for test PyPI and GitHub release #95
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
8063f0c
b643887
7fea5c0
8908c9b
fe7d673
b0228b0
f7a4242
6fe0782
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,84 @@ | ||
| name: Release | ||
| on: | ||
| workflow_dispatch: | ||
| push: | ||
| tags: | ||
| - '*' | ||
| permissions: | ||
| contents: write | ||
| jobs: | ||
| build-package: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ github.ref }} | ||
| - uses: hynek/build-and-inspect-python-package@v2 | ||
|
|
||
| update-changelog: | ||
| needs: [build-package] | ||
| if: "!contains(github.ref, 'rc')" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if it has no |
||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout the repository | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ github.ref }} | ||
|
|
||
| - name: Update CHANGELOG.rst wit the latest news | ||
| run: python .github/workflows/update-changelog.py "${{ github.ref_name }}" | ||
|
|
||
| - name: Commite the changes in CHANGELOG.rst | ||
| uses: stefanzweifel/git-auto-commit-action@v5 | ||
| with: | ||
| commit_message: update changelog | ||
| branch: pypi-build # FIXME: change to main | ||
|
|
||
| github-pre-release: | ||
| needs: [build-package] | ||
| if: contains(github.ref, 'rc') | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Generate GH release notes for pre-release | ||
| uses: softprops/action-gh-release@v2 | ||
| with: | ||
| draft: true | ||
| prerelease: true | ||
| generate_release_notes: true | ||
|
|
||
| github-release: | ||
| needs: [build-package, update-changelog] | ||
| if: "!contains(github.ref, 'rc')" | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout the repository | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| ref: pypi-build # FIXME: change to main | ||
| - name: Generate GH release notes for release | ||
| run: python .github/workflows/get-latest-changelog.py "${{ github.ref_name }}" | ||
| - name: Release | ||
| uses: softprops/action-gh-release@v2 | ||
| with: | ||
| body_path: CHANGELOG.txt | ||
| draft: true | ||
|
|
||
| pypi-publish: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Upload to pypi - right now test.pypi is used for testing. |
||
| needs: [build-package] | ||
| environment: | ||
| name: testpypi # FIXME: change to pypi | ||
| url: https://test/pypi.org/p/diffpy.snmf # FIXME: get the PyPI URL | ||
| permissions: | ||
| id-token: write | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/download-artifact@v4 | ||
| with: | ||
| name: Packages | ||
| path: dist | ||
|
|
||
| - name: Publish package distributions to PyPI | ||
| uses: pypa/gh-action-pypi-publish@release/v1 | ||
| with: | ||
| repository-url: https://test.pypi.org/legacy/ # FIXME: remove test. | ||
| verbose: true | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| import re | ||
| import sys | ||
|
|
||
|
|
||
| def get_tag_news_items(tag, filepath): | ||
| """Collect news items after the specified tag until the next version is found.""" | ||
| collect = False | ||
| collected_lines = [] | ||
| # Regex to match version numbers | ||
| version_pattern = re.compile(r"^\d+\.\d+\.\d+") | ||
|
|
||
| with open(filepath, "r") as file: | ||
| for line in file: | ||
| if line.strip().startswith(tag): | ||
| collect = True | ||
| continue | ||
| elif collect and version_pattern.match(line.strip()): | ||
| break | ||
| elif collect: | ||
| collected_lines.append(line.rstrip()) | ||
|
|
||
| return collected_lines | ||
|
|
||
|
|
||
| def remove_two_lines(lines): | ||
| """Remove two lines after the tag in CHANGELOG.rst.""" | ||
| if lines: | ||
| # Remove the first line containing "====" | ||
| if "====" in lines[0]: | ||
| lines.pop(0) | ||
| # Remove the second empty line | ||
| if lines[1] == "": | ||
| lines.pop(1) | ||
| return lines | ||
|
|
||
|
|
||
| def save_to_txt_file(lines, filename): | ||
| """Save collected lines to a .txt file used for GH release notes.""" | ||
| output = "\n".join(lines) | ||
| with open(filename, "w") as file: | ||
| file.write(output) | ||
| return output | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| if len(sys.argv) < 2: | ||
| assert ( | ||
| False | ||
| ), "No tag has been provided. Please provide a tag by running python get-latest-changelog.py <tag>" | ||
|
|
||
| tag = sys.argv[1] | ||
| CHANGELOG_PATH = "CHANGELOG.rst" | ||
| LATEST_CHANGELOG_PATH = "CHANGELOG.txt" | ||
|
|
||
| collected_lines = get_tag_news_items(tag, CHANGELOG_PATH) | ||
| cleaned_lines = remove_two_lines(collected_lines) | ||
| latest_changelog_output = save_to_txt_file(cleaned_lines, LATEST_CHANGELOG_PATH) | ||
| print(f"CHANGELOG for {tag}:\n{latest_changelog_output}") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| import os | ||
| import sys | ||
| from glob import glob | ||
|
|
||
| # Get the GitHub reference passed as an argument | ||
| tag = sys.argv[1] | ||
|
|
||
| # Store category data | ||
| news_items = { | ||
| "Added": [], | ||
| "Changed": [], | ||
| "Deprecated": [], | ||
| "Removed": [], | ||
| "Fixed": [], | ||
| "Security": [], | ||
| } | ||
|
|
||
|
|
||
| def extract_news_items(file_path): | ||
| """Extract news bullet points under each category for each .rst file.""" | ||
| with open(file_path, "r") as file: | ||
| for line in file: | ||
| line = line.strip() | ||
|
|
||
| # Check if the line is a category header | ||
| if line.startswith("**") and line.endswith(":**"): | ||
| current_category = line.strip("**:").strip() | ||
|
|
||
| # Only add if the line is not empty and not a category header | ||
| elif current_category and line and not line.startswith("* <news item>"): | ||
| news_items[current_category].append(line) | ||
|
|
||
|
|
||
| def write_merged_file(): | ||
| """Add the news items under the ".. current developments" section.""" | ||
| CHANGELOG_PATH = "CHANGELOG.rst" | ||
| CHANGELOG_HEADER = ".. current developments" | ||
|
|
||
| # Insert news | ||
| new_news_content = f"\n{tag}\n=====\n\n" | ||
| for category_name in sorted(news_items.keys()): | ||
| items = news_items[category_name] | ||
| if items: | ||
| # Add category name e.g. Added, Changed, etc. | ||
| new_news_content += f"**{category_name}:**\n\n" | ||
| for item in items: | ||
| # Add each item in the category | ||
| new_news_content += f"{item}\n" | ||
| new_news_content += "\n" | ||
|
|
||
| # Read CHANGELOG.rst | ||
| with open(CHANGELOG_PATH, "r") as file: | ||
| current_content = file.read() | ||
|
|
||
| # Find the position to insert news after ".. current developments" | ||
| insert_position = current_content.find(CHANGELOG_HEADER) + len(CHANGELOG_HEADER) + 1 | ||
| final_content = current_content[:insert_position] + new_news_content + current_content[insert_position:] | ||
|
|
||
| # Write the updated content back to the file | ||
| with open(CHANGELOG_PATH, "w") as file: | ||
| file.write(final_content) | ||
|
|
||
| return new_news_content | ||
|
|
||
|
|
||
| def remove_news_rst_files(news_dir_path): | ||
| """Remove .rst files in the news directory except TEMPLATE.rst""" | ||
| rst_files = os.listdir(news_dir_path) | ||
| for file_name in rst_files: | ||
| rst_file_path = os.path.join(news_dir_path, file_name) | ||
| if file_name.endswith(".rst") and file_name != "TEMPLATE.rst": | ||
| os.remove(rst_file_path) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| NEWS_DIR_PATH = "news" | ||
|
|
||
| # Get all news .rst files | ||
| news_rst_files = glob(os.path.join(NEWS_DIR_PATH, "*.rst")) | ||
|
|
||
| # Extract and store news items into a single dictionary | ||
| for rst_file in news_rst_files: | ||
| extract_news_items(rst_file) | ||
|
|
||
| # Add news under ".. current developments" | ||
| new_news_content = write_merged_file() | ||
|
|
||
| # Remove all .rst files in the news directory except TEMPLATE.rst | ||
| remove_news_rst_files(NEWS_DIR_PATH) | ||
|
|
||
| # Print for debugging | ||
| print(new_news_content) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| **Added:** | ||
|
|
||
| * GitHub workflow files for PyPI and GH release | ||
|
|
||
| **Changed:** | ||
|
|
||
| * <news item> | ||
|
|
||
| **Deprecated:** | ||
|
|
||
| * <news item> | ||
|
|
||
| **Removed:** | ||
|
|
||
| * <news item> | ||
|
|
||
| **Fixed:** | ||
|
|
||
| * <news item> | ||
|
|
||
| **Security:** | ||
|
|
||
| * <news item> |
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.
Produce wheel/sdist, have them available under
dist