Skip to content

Commit

Permalink
Merge pull request #59201 from qgis/vcpkg-update-comment
Browse files Browse the repository at this point in the history
Create vcpkg package update report
  • Loading branch information
m-kuhn authored Oct 24, 2024
2 parents bb5caef + 2077dc4 commit 20073da
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 2 deletions.
49 changes: 49 additions & 0 deletions .github/actions/vcpkg_update_report/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Compare vcpkg install changes
description: Compares vcpkg install outputs between the base and head refs on pull requests and generates a report.

inputs:
vcpkg-manifest-dir:
description: 'Directory containing the vcpkg.json manifest'
required: true
default: '.'
type: string
triplet:
description: 'Triplet to use for vcpkg installation'
required: true
default: 'x64-linux'
type: string

outputs:
report:
description: 'The report of added and removed packages after vcpkg installation comparison'
value: ${{ steps.compare.outputs.report }}

runs:
using: "composite"
steps:
# Run vcpkg install --dry-run on the head ref
- name: Run vcpkg install (HEAD)
shell: bash
run: |
vcpkg install --dry-run --triplet ${{ inputs.triplet }} --x-manifest-root=${{ inputs.vcpkg-manifest-dir }} > /tmp/vcpkg-head-output.txt
# Run vcpkg install --dry-run on the base ref
- name: Run vcpkg install (BASE)
shell: bash
run: |
git worktree add .base-ref ${{ github.event.pull_request.base.sha }}
vcpkg install --dry-run --triplet ${{ inputs.triplet }} --x-manifest-root=.base-ref/${{ inputs.vcpkg-manifest-dir }} > /tmp/vcpkg-base-output.txt
# Compare the outputs and generate a report
- name: Compare vcpkg outputs
shell: bash
id: compare
run: |
python3 ${GITHUB_ACTION_PATH}/vcpkg-diff.py > /tmp/vcpkg-report.txt
cat /tmp/vcpkg-report.txt
{
echo 'report<<EOF'
cat /tmp/vcpkg-report.txt
echo EOF
} >> "$GITHUB_OUTPUT"
101 changes: 101 additions & 0 deletions .github/actions/vcpkg_update_report/vcpkg-diff.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import re


def extract_packages(data):
"""
Extract package name, triplet, version, and features information from the file content.
"""
packages = {}
lines = data.strip().split("\n")
for line in lines:
# Regex to match the package format and capture features inside brackets
match = re.match(
r"\s*\*\s+([^\[\]:]+)(?:\[(.*?)\])?:([^\[\]@]+)@([^\s]+)\s+--", line
)
if match:
package_name = match.group(1)
features = match.group(2) if match.group(2) else ""
triplet = match.group(3)
version = match.group(4)
features_list = (
[feature.strip() for feature in features.split(",")] if features else []
)
packages[package_name] = (triplet, version, features_list)
return packages


def compare_features(features1, features2):
"""
Compare two feature lists and return the differences.
"""
added_features = set(features2) - set(features1)
removed_features = set(features1) - set(features2)
return added_features, removed_features


def generate_report(file1_content, file2_content):
# Extract package information from both files
file1_packages = extract_packages(file1_content)
file2_packages = extract_packages(file2_content)

added = []
removed = []
updated = []

# Identify removed and updated packages
for pkg in file1_packages:
if pkg not in file2_packages:
removed.append(pkg)
else:
# Compare version and features
triplet1, version1, features1 = file1_packages[pkg]
triplet2, version2, features2 = file2_packages[pkg]
updated_parts = []
if version1 != version2 or triplet1 != triplet2:
updated_parts.append(f"{version1} -> {version2}")
added_features, removed_features = compare_features(features1, features2)
if added_features:
updated_parts.append("+" + ", ".join(added_features))
if removed_features:
updated_parts.append("-" + ", ".join(removed_features))
if updated_parts:
updated.append(f"{pkg}: " + " ".join(updated_parts))

# Identify added packages
for pkg in file2_packages:
if pkg not in file1_packages:
added.append(pkg)

# Print the report
if added:
print("**Added packages:**")
for pkg in added:
triplet, version, features = file2_packages[pkg]
print(f" 🍓 {pkg}: {version} (Features: {', '.join(features)})")

if removed:
print("\n**Removed packages:**")
for pkg in removed:
triplet, version, features = file1_packages[pkg]
print(f" 🍄 {pkg}: {version} (Features: {', '.join(features)})")

if updated:
print("\n**Updated packages:**")
for pkg in updated:
print(f" 🍇 {pkg}")


def read_file(file_path):
"""
Read the content of a file.
"""
with open(file_path, "r") as file:
return file.read()


# Read files
file1_content = read_file("/tmp/vcpkg-base-output.txt")
file2_content = read_file("/tmp/vcpkg-head-output.txt")

# Generate the report
generate_report(file1_content, file2_content)
35 changes: 35 additions & 0 deletions .github/workflows/vcpkg-update-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
name: 🧮 Vcpkg report
on:
pull_request:
paths:
- 'vcpkg/**'

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
vcpkg-check:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 30

- name: Generate diff report
id: vcpkg_diff
uses: ./.github/actions/vcpkg_update_report
with:
vcpkg-manifest-dir: vcpkg
triplet: x64-linux

- name: Schedule report comment
uses: ./.github/actions/post_sticky_comment
if: github.event_name == 'pull_request'
with:
marker: vcpkg-report
body: |
### 🧮 Vcpkg update report
${{ steps.vcpkg_diff.outputs.report }}
pr: ${{ github.event.number }}
3 changes: 1 addition & 2 deletions vcpkg/vcpkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
"vcpkg-configuration": {
"default-registry": {
"kind": "git",
"baseline": "7adc2e4d49e8d0efc07a369079faa6bc3dbb90f3",
"reference": "7adc2e4d49e8d0efc07a369079faa6bc3dbb90f3",
"baseline": "41626fd77bf42f29e8f7e43dc1f2f05780588cde",
"repository": "https://github.com/microsoft/vcpkg"
},
"registries": [
Expand Down

0 comments on commit 20073da

Please sign in to comment.