Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/workflows/apply_sync_hold.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
name: Apply sync hold
# this is fine since gha runs with yaml 1.2
on: # yamllint disable-line rule:truthy
workflow_dispatch:
inputs:
distribution:
description: 'Which distribution is in sync hold?'
required: true
type: choice
options:
- 'jazzy'
- 'kilted'
- 'lyrical'
- 'rolling'
default: 'rolling'
jobs:
apply-sync-hold:
Comment thread
asymingt marked this conversation as resolved.
Outdated
permissions:
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Add a sync hold label to PRs
env:
GH_TOKEN: ${{ github.token }}
TARGET_FILE: "${{ inputs.distribution }}/distribution.yaml"
LABEL_TO_ADD: "held for ${{ inputs.distribution }} sync"
run: |
# Find all PRs that touch the target file ...
PR_NUMBERS=$(gh pr list --state open --json number,files | \
jq -r --arg FILE "${{ env.TARGET_FILE }}" '.[] | select(.files[].path == $FILE) | .number')

# Special case: nothing needs to be held for sync so bail early.
if [ -z "$PR_NUMBERS" ]; then
echo "No PRs found touching ${{ env.TARGET_FILE }}"
exit 0
fi

# Loop through and remove the label
for PR in $PR_NUMBERS; do
echo "Processing PR #$PR..."
gh pr edit $PR --add-label "${{ env.LABEL_TO_ADD }}" || echo "Label not found on #$PR"
done
135 changes: 135 additions & 0 deletions .github/workflows/cut_new_release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
---
name: Cut a new ROS release
# this is fine since gha runs with yaml 1.2
on: # yamllint disable-line rule:truthy
workflow_dispatch:
inputs:
distribution:
description: 'Which distribution is the release for?'
required: true
type: choice
options:
- 'jazzy'
- 'kilted'
- 'lyrical'
- 'rolling'
default: 'rolling'
date:
description: 'Release in YYYY-MM-DD. Leave empty for new.'
required: false
type: string
remove_held_for_sync_tags:
description: 'Remove all held-for-sync labels?'
required: true
type: boolean
default: true
jobs:
cut-new-release:
permissions:
pull-requests: write
contents: write
runs-on: ubuntu-latest
steps:
# Add any missing inputs.
- name: Calculate final inputs
env:
OLD_CACHE_URL_BASE: "http://repo.ros2.org/rosdistro_cache"
NEW_CACHE_URL_BASE: "https://github.com/ros/rosdistro/releases/download"
run: |
USER_INPUT="${{ inputs.date }}"
if [ -z "$USER_INPUT" ]; then
FINAL_DATE=$(TZ="America/Los_Angeles" date +%Y-%m-%d)
FINAL_REF=master
echo "Date used: $FINAL_DATE (branch: $FINAL_REF, must exist)"
else
FINAL_DATE=$USER_INPUT
FINAL_REF=${{ inputs.distribution }}/$FINAL_DATE
echo "Date provided: $FINAL_DATE (tag: $FINAL_REF, must exist)"
fi
OLD_URL_SUFFIX=${{ inputs.distribution }}-cache.yaml.gz
NEW_URL_SUFFIX=${{ inputs.distribution }}/$FINAL_DATE/${{ inputs.distribution }}-cache.yaml.gz
echo "RELEASE_DISTRIBUTION=${{ inputs.distribution }}" >> $GITHUB_ENV
echo "RELEASE_DATE=$FINAL_DATE" >> $GITHUB_ENV
echo "RELEASE_REF=$FINAL_REF" >> $GITHUB_ENV
echo "RELEASE_TAG=${{ inputs.distribution }}/$FINAL_DATE" >> $GITHUB_ENV
echo "RELEASE_CACHE_OLD_URL=${{ env.OLD_CACHE_URL_BASE }}/$OLD_URL_SUFFIX" >> $GITHUB_ENV
echo "RELEASE_CACHE_NEW_URL=${{ env.NEW_CACHE_URL_BASE }}/$NEW_URL_SUFFIX" >> $GITHUB_ENV

# Echo the release information to console.
- name: Print release information
run: |
echo "Ref: ${{ env.RELEASE_REF }}"
echo "Distribution: ${{ env.RELEASE_DISTRIBUTION }}"
echo "Date: ${{ env.RELEASE_DATE }}"
echo "Tag: ${{ env.RELEASE_TAG }}"
echo "Old cache URL: ${{ env.RELEASE_CACHE_OLD_URL }}"
echo "New cache URL: ${{ env.RELEASE_CACHE_NEW_URL }}"

# Checkout the repository master branch.
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ env.RELEASE_REF }}

# Set up a clean Python environment (Avoids OS-level pip blocks)
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'

# Install dependencies for the rosdistro_build_cache tool.
- name: Install extra tools via pip
run: |
python -m pip install --upgrade pip
pip install rosdistro

# Rebuild the cache from scratch.
- name: Rebuild cache
run: |
cd ${{ env.RELEASE_DISTRIBUTION }}
sed -i "s|https://github.com/ros-gbp|https://github.com/ros2-gbp|g" distribution.yaml
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workaround can't make it into production. If there's a bug in the index, it should be fixed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point. I forgot about this step in the workflow. It won't be needed going forward as the GBP repos are correct on master. I needed this workaround when trying to rebuild a distribution cache for an older release in 2025. Fixing the error in the way you suggest would be rewriting git history, which I assume can't happen. Is it ok if I just remove this step completely?

rosdistro_build_cache ../index-v4.yaml ${{ env.RELEASE_DISTRIBUTION }}
cd ..

# Commit the change to the distribution file and push the tagged orphaned commit.
- name: Tag orphaned commit for the release
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
sed -i "s|${{ env.RELEASE_CACHE_OLD_URL }}|${{ env.RELEASE_CACHE_NEW_URL }}|g" index.yaml
sed -i "s|${{ env.RELEASE_CACHE_OLD_URL }}|${{ env.RELEASE_CACHE_NEW_URL }}|g" index-v4.yaml
git add index.yaml index-v4.yaml
git commit -m "chore: update cache entry for ${{ env.RELEASE_DISTRIBUTION }}"
git tag -f ${{ env.RELEASE_TAG }}
git push -f origin tags/${{ env.RELEASE_TAG }}

# Force-push the release.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we force-pushing to rosdistro?

Copy link
Copy Markdown
Contributor Author

@asymingt asymingt Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To overwrite an existing tag from the past if we choose to update it to include the distribution cache artifacts. If we plan to use this action strictly for future releases then it should be fine to remove the force in this command. Would that work for you?

- name: Push release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ env.RELEASE_TAG }}
files: |
${{ env.RELEASE_DISTRIBUTION }}/${{ env.RELEASE_DISTRIBUTION }}-cache.yaml.gz

# Find all PRs with the sync label and remove them.
- name: Remove all held for sync labels on PRs
if: ${{ inputs.remove_held_for_sync_tags == true }}
env:
GH_TOKEN: ${{ github.token }}
LABEL_TO_REMOVE: "held for ${{ inputs.distribution }} sync"
run: |
# Get all open PRs that have a held for sync label matching the current release.
PR_NUMBERS=$(gh pr list --state open --label "${{ env.LABEL_TO_REMOVE }}" --json number --jq '.[].number')

# Special case: nothing was held for sync so bail early.
if [ -z "$PR_NUMBERS" ]; then
echo "No PRs found with label: ${{ env.LABEL_TO_REMOVE }}"
exit 0
fi

# Loop through PRs that match and remove the label.
for PR in $PR_NUMBERS; do
echo "Processing PR #$PR..."
gh pr edit $PR --remove-label "${{ env.LABEL_TO_REMOVE }}" || echo "Label not found on #$PR"
done
Loading