Skip to content

Sync upstream and create version tags #350

Sync upstream and create version tags

Sync upstream and create version tags #350

Workflow file for this run

name: Sync upstream and create version tags
on:
schedule:
- cron: "17 3 * * *" # Daily at 03:17 UTC
workflow_dispatch:
inputs:
dry_run:
description: "Run without pushing branches/tags or creating releases"
required: false
default: false
type: boolean
trigger_releases:
description: "Trigger release workflow for newly-created tags"
required: false
default: true
type: boolean
concurrency:
group: upstream-sync
cancel-in-progress: false
jobs:
sync-and-tag:
runs-on: ubuntu-latest
permissions:
contents: write
actions: write
env:
DRY_RUN: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run }}
TRIGGER_RELEASES: ${{ github.event_name != 'workflow_dispatch' || inputs.trigger_releases }}
steps:
- name: Checkout ci branch
uses: actions/checkout@v4
with:
ref: ci
fetch-depth: 0
- name: Configure git identity
run: |
git config user.name 'github-actions[bot]'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
- name: Fetch all origin refs
run: |
git fetch origin '+refs/heads/*:refs/remotes/origin/*' --prune
git fetch origin --tags --prune-tags
- name: Add upstream remote and fetch
run: |
git remote add upstream https://github.com/VirtualBox/virtualbox.git
git fetch upstream '+refs/heads/*:refs/remotes/upstream/*' --prune
- name: Sync branches from upstream
shell: bash
run: |
set -euo pipefail
sync_branch() {
local upstream_ref="$1"
local branch="$2"
local upstream_sha
local origin_sha
upstream_sha="$(git rev-parse "$upstream_ref")"
origin_sha="$(git rev-parse "refs/remotes/origin/$branch" 2>/dev/null || true)"
if [[ "$upstream_sha" == "$origin_sha" ]]; then
echo "$branch already up to date at ${upstream_sha:0:12}"
return
fi
if [[ "$DRY_RUN" == "true" ]]; then
echo "[dry-run] would sync $branch to ${upstream_sha:0:12}"
return
fi
echo "syncing $branch to ${upstream_sha:0:12}"
git push --force-with-lease origin "$upstream_ref:refs/heads/$branch"
}
echo "::group::Syncing main"
sync_branch upstream/main main
echo "::endgroup::"
while IFS= read -r ref; do
branch="${ref#upstream/}"
echo "::group::Syncing $branch"
sync_branch "$ref" "$branch"
echo "::endgroup::"
done < <(git for-each-ref --format='%(refname:short)' refs/remotes/upstream/ | grep '^upstream/VBox-' | sort || true)
- name: Create version tags
id: tags
shell: bash
run: |
set -euo pipefail
args=(--output new-tags.txt)
if [[ "$DRY_RUN" == "true" ]]; then
args+=(--dry-run)
else
args+=(--push)
fi
chmod +x .github/scripts/create-version-tags.sh
.github/scripts/create-version-tags.sh "${args[@]}"
{
echo 'created_tags<<EOF'
cat new-tags.txt
echo 'EOF'
} >>"$GITHUB_OUTPUT"
- name: Trigger release workflow for new tags
if: ${{ env.DRY_RUN != 'true' && env.TRIGGER_RELEASES == 'true' && steps.tags.outputs.created_tags != '' }}
env:
GH_TOKEN: ${{ github.token }}
CREATED_TAGS: ${{ steps.tags.outputs.created_tags }}
shell: bash
run: |
set -euo pipefail
while IFS= read -r tag; do
[[ -n "$tag" ]] || continue
echo "triggering release workflow for $tag"
gh workflow run release.yml --ref ci -f tag="$tag"
done <<<"$CREATED_TAGS"
- name: Write job summary
if: always()
shell: bash
run: |
{
echo '## Upstream sync'
echo ""
echo "Dry run: \`$DRY_RUN\`"
echo "Trigger releases: \`$TRIGGER_RELEASES\`"
echo ""
echo '## New tags'
echo ""
if [[ -s new-tags.txt ]]; then
sed 's/^/- /' new-tags.txt
else
echo 'No new tags detected.'
fi
} >>"$GITHUB_STEP_SUMMARY"