From a9aab9071dedf2814fdc41f5ecb30c8032ef35d1 Mon Sep 17 00:00:00 2001 From: BDevParity Date: Wed, 18 Feb 2026 13:38:39 +0100 Subject: [PATCH] BACKPORT-CONFLICT --- ...ease-60_post-crates-release-activities.yml | 63 ++++- .../workflows/release-80_publish-crates.yml | 263 ++++++++++++++++++ scripts/release/replace-all-path-deps.sh | 3 +- 3 files changed, 316 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/release-80_publish-crates.yml diff --git a/.github/workflows/release-60_post-crates-release-activities.yml b/.github/workflows/release-60_post-crates-release-activities.yml index dfb1bd3a74852..5d4d6bf34cb66 100644 --- a/.github/workflows/release-60_post-crates-release-activities.yml +++ b/.github/workflows/release-60_post-crates-release-activities.yml @@ -27,7 +27,14 @@ permissions: pull-requests: write jobs: + #check-synchronization: + # uses: paritytech-release/sync-workflows/.github/workflows/check-synchronization.yml@main + #secrets: + # fork_writer_app_key: ${{ secrets.UPSTREAM_CONTENT_SYNC_APP_KEY }} + set-image: + #needs: [ check-synchronization ] + #if: needs.check-synchronization.outputs.checks_passed == 'true' runs-on: ubuntu-latest outputs: IMAGE: ${{ steps.set_image.outputs.IMAGE }} @@ -283,9 +290,18 @@ jobs: echo "No changes to commit" fi + - name: Generate token for paritytech/polkadot-sdk + id: generate_write_token + uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 + with: + app-id: ${{ vars.POLKADOT_SDK_RELEASE_RW_APP_ID }} + private-key: ${{ secrets.POLKADOT_SDK_RELEASE_RW_APP_KEY }} + owner: paritytech + repositories: polkadot-sdk + - name: Create Pull Request to base release branch env: - GH_TOKEN: ${{ github.token }} + GH_TOKEN: ${{ steps.generate_write_token.outputs.token }} shell: bash run: | BRANCH_NAME="${{ github.ref_name }}" @@ -300,15 +316,30 @@ jobs: BASE_RELEASE="$FULL_RELEASE" fi + TARGET_REPO="paritytech/polkadot-sdk" + + # Determine if running from a fork or the main repo + if [ "${{ github.repository }}" = "$TARGET_REPO" ]; then + # Same-repo PR: head is just the branch name + PR_HEAD="$BRANCH_NAME" + EXTRA_FLAGS="" + else + # Cross-fork PR: head needs the fork owner prefix + FORK_OWNER="${{ github.repository_owner }}" + PR_HEAD="${FORK_OWNER}:${BRANCH_NAME}" + EXTRA_FLAGS="--no-maintainer-edit" + fi + # Check if PR already exists - EXISTING_PR=$(gh pr list --head "$BRANCH_NAME" --base "$BASE_RELEASE" --json number --jq '.[0].number') + EXISTING_PR=$(gh pr list --repo "$TARGET_REPO" --head "$PR_HEAD" --base "$BASE_RELEASE" --json number --jq '.[0].number') if [ -n "$EXISTING_PR" ]; then echo "✅ PR #$EXISTING_PR already exists for this branch" - echo "PR URL: $(gh pr view $EXISTING_PR --json url --jq '.url')" + echo "PR URL: $(gh pr view $EXISTING_PR --repo "$TARGET_REPO" --json url --jq '.url')" else - echo "Creating PR from $BRANCH_NAME to $BASE_RELEASE..." + echo "Creating PR from $PR_HEAD to $BASE_RELEASE in $TARGET_REPO..." gh pr create \ + --repo "$TARGET_REPO" \ --title "[${BASE_RELEASE}] Post crates release activities for $FULL_RELEASE" \ --body "Automated PR containing post-crates-release activities: - NODE_VERSION bumps (if selected) @@ -317,23 +348,33 @@ jobs: - Taplo formatting - PRDocs reorganization (if prdocs exist)" \ --base "$BASE_RELEASE" \ - --head "$BRANCH_NAME" - echo "✅ PR created successfully" + --head "$PR_HEAD" \ + $EXTRA_FLAGS + echo "PR created successfully" fi - name: Add comment about spec_version env: - GH_TOKEN: ${{ github.token }} + GH_TOKEN: ${{ steps.generate_write_token.outputs.token }} shell: bash run: | BRANCH_NAME="${{ github.ref_name }}" + TARGET_REPO="paritytech/polkadot-sdk" + + # Match the head format used when creating the PR + if [ "${{ github.repository }}" = "$TARGET_REPO" ]; then + PR_HEAD="$BRANCH_NAME" + else + FORK_OWNER="${{ github.repository_owner }}" + PR_HEAD="${FORK_OWNER}:${BRANCH_NAME}" + fi - # Find the PR number for this branch - PR_NUMBER=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number') + # Find the PR number for this branch in the upstream repo + PR_NUMBER=$(gh pr list --repo "$TARGET_REPO" --head "$PR_HEAD" --json number --jq '.[0].number') if [ -n "$PR_NUMBER" ]; then echo "Adding comment to PR #$PR_NUMBER..." - gh pr comment "$PR_NUMBER" --body "⚠️ **Reminder:** spec_version is not bumped automatically as part of this flow. Please ensure it is updated manually if required." + gh pr comment "$PR_NUMBER" --repo "$TARGET_REPO" --body "⚠️ **Reminder:** If spec_version was not bumped automatically as part of this flow. Please ensure it is updated manually if required." else - echo "WARNING: Could not find PR for branch $BRANCH_NAME" + echo "⚠️ WARNING: Could not find PR for branch $PR_HEAD" fi diff --git a/.github/workflows/release-80_publish-crates.yml b/.github/workflows/release-80_publish-crates.yml new file mode 100644 index 0000000000000..382e0f3d4bde6 --- /dev/null +++ b/.github/workflows/release-80_publish-crates.yml @@ -0,0 +1,263 @@ +name: Release - Publish Crates + +on: + workflow_dispatch: + inputs: + release_name: + description: 'Release name (e.g., stable2509-3). Base branch is derived by removing the last -N suffix.' + required: true + type: string + registry: + description: 'Registry to publish crates to' + required: true + type: choice + options: + - staging.crates.io + - crates.io + default: staging.crates.io + is_patch: + description: 'Is this a patch release? (Set to false for new stable releases)' + required: true + type: boolean + default: true + dry_run: + description: 'Dry run - do not actually publish crates' + required: true + type: boolean + default: true + +permissions: + contents: write + +jobs: + check-synchronization: + uses: paritytech-release/sync-workflows/.github/workflows/check-synchronization.yml@main + secrets: + fork_writer_app_key: ${{ secrets.UPSTREAM_CONTENT_SYNC_APP_KEY }} + + set-image: + needs: [ check-synchronization ] + if: needs.check-synchronization.outputs.checks_passed == 'true' + runs-on: ubuntu-latest + outputs: + IMAGE: ${{ steps.set_image.outputs.IMAGE }} + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - id: set_image + run: cat .github/env >> $GITHUB_OUTPUT + + publish-crates: + needs: set-image + runs-on: ubuntu-latest + environment: release + env: + PGP_KMS_KEY: ${{ secrets.PGP_KMS_SIGN_COMMITS_KEY }} + PGP_KMS_HASH: ${{ secrets.PGP_KMS_HASH }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + container: + image: ${{ needs.set-image.outputs.IMAGE }} + + steps: + - name: Install pgpkms + run: | + # Install pgpkms that is used to sign commits + pip install git+https://github.com/paritytech-release/pgpkms.git@6cb1cecce1268412189b77e4b130f4fa248c4151 + + - name: Derive stable branch from release name + id: derive_branch + shell: bash + run: | + RELEASE_NAME="${{ inputs.release_name }}" + echo "Release name: $RELEASE_NAME" + + # Extract stable branch by removing the last -N suffix + # e.g., stable2509-3 -> stable2509 + if [[ "$RELEASE_NAME" =~ ^(.+)-[0-9]+$ ]]; then + STABLE_BRANCH="${BASH_REMATCH[1]}" + else + # If no suffix, use the release name as-is (first release) + STABLE_BRANCH="$RELEASE_NAME" + fi + + echo "Stable branch: $STABLE_BRANCH" + echo "STABLE_BRANCH=$STABLE_BRANCH" >> $GITHUB_OUTPUT + + echo "CRATES_RELEASE_BRANCH=post-crates-release-$RELEASE_NAME" >> $GITHUB_OUTPUT + + - name: Checkout stable branch + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ steps.derive_branch.outputs.STABLE_BRANCH }} + fetch-depth: 0 + + - name: Import GPG keys + shell: bash + run: | + . ./.github/scripts/common/lib.sh + import_gpg_keys + + - name: Configure git + shell: bash + run: | + git config --global --add safe.directory "${GITHUB_WORKSPACE}" + git config --global commit.gpgsign true + PGPKMS_PATH=$(which pgpkms-git) + echo "Using pgpkms-git at: $PGPKMS_PATH" + git config --global gpg.program "$PGPKMS_PATH" + git config --global user.name "ParityReleases" + git config --global user.email "release-team@parity.io" + git config --global user.signingKey "D8018FBB3F534D866A45998293C5FB5F6A367B51" + + - name: Create or switch to release branch + shell: bash + run: | + CRATES_RELEASE_BRANCH="${{ steps.derive_branch.outputs.CRATES_RELEASE_BRANCH }}" + + if git rev-parse --verify -q "$CRATES_RELEASE_BRANCH" &>/dev/null; then + echo "Branch $CRATES_RELEASE_BRANCH already exists, switching to it" + git checkout "$CRATES_RELEASE_BRANCH" + else + echo "Creating branch: $CRATES_RELEASE_BRANCH" + git checkout -b "$CRATES_RELEASE_BRANCH" + fi + echo "On branch $CRATES_RELEASE_BRANCH" + + - name: Install Rust 1.93 + shell: bash + run: | + rustup install 1.93 + rustup default 1.93 + echo "Rust version:" + rustc --version + cargo --version + + - name: Rust Cache + uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2 + with: + cache-on-failure: true + + - name: Install parity-publish + run: | + apt-get update && apt-get install -y --no-install-recommends libcurl4-openssl-dev pkg-config + cargo install parity-publish@0.10.10 --locked -q + + - name: Run parity-publish plan + run: | + echo "Running parity-publish plan..." + parity-publish plan --prdoc prdoc + + - name: Save Plan.toml diff + if: inputs.is_patch + run: | + RELEASE_NAME="${{ inputs.release_name }}" + mkdir -p release-artifacts + + echo "Saving Plan.toml diff..." + git diff Plan.toml > "release-artifacts/changed_crates_${RELEASE_NAME}.txt" + + echo "Plan.toml changes:" + cat "release-artifacts/changed_crates_${RELEASE_NAME}.txt" + + - name: Parse crate names for release notes + if: inputs.is_patch + shell: bash + run: | + RELEASE_NAME="${{ inputs.release_name }}" + + echo "Parsing crate names..." + python3 scripts/release/parse-crates-names.py \ + "release-artifacts/changed_crates_${RELEASE_NAME}.txt" \ + scripts/release/templates/crates_list.md.tera + + echo "Crates list:" + cat scripts/release/templates/crates_list.md.tera + + - name: Commit Plan.toml and crates list + shell: bash + run: | + . ./.github/scripts/release/release_lib.sh + + git add Plan.toml + if [ "${{ inputs.is_patch }}" = true ]; then + git add scripts/release/templates/crates_list.md.tera + fi + + if [[ -n $(git status --porcelain) ]]; then + commit_with_message "chore: update Plan.toml and crates list for ${{ inputs.release_name }}" + echo "Committed Plan.toml and crates list" + else + echo "No changes to commit" + fi + + - name: Run parity-publish apply + run: | + echo "Running parity-publish apply..." + parity-publish apply + + - name: Update Cargo.lock + run: | + echo "Updating Cargo.lock..." + cargo update --workspace --offline || cargo update --workspace + echo "Cargo.lock updated" + + - name: Commit version bumps + shell: bash + run: | + . ./.github/scripts/release/release_lib.sh + + git add -A + + if [[ -n $(git status --porcelain) ]]; then + commit_with_message "chore: apply version bumps for ${{ inputs.release_name }}" + echo "Committed version bumps" + else + echo "No changes to commit" + fi + + - name: Push release branch + run: | + CRATES_RELEASE_BRANCH="${{ steps.derive_branch.outputs.CRATES_RELEASE_BRANCH }}" + echo "Pushing branch $CRATES_RELEASE_BRANCH..." + git push origin "$CRATES_RELEASE_BRANCH" + echo "Successfully pushed $CRATES_RELEASE_BRANCH" + + - name: Configure cargo registry + shell: bash + run: | + REGISTRY="${{ inputs.registry }}" + echo "Configuring cargo for $REGISTRY..." + mkdir -p ~/.cargo + + if [ "$REGISTRY" = "staging.crates.io" ]; then + cat >> ~/.cargo/config.toml << 'EOF' + [registries.crates-io] + index = "sparse+https://index.staging.crates.io/" + EOF + else + echo "Using default crates.io registry" + fi + + echo "Cargo config:" + cat ~/.cargo/config.toml || echo "(using defaults)" + + - name: Publish crates + shell: bash + env: + PARITY_PUBLISH_CRATESIO_TOKEN: ${{ inputs.registry == 'staging.crates.io' && secrets.STAGING_CRATES_IO_API_TOKEN || secrets.CRATES_IO_API_TOKEN }} + run: | + DRY_RUN="${{ inputs.dry_run }}" + REGISTRY="${{ inputs.registry }}" + + if [ "$DRY_RUN" = true ]; then + echo "DRY RUN - Not actually publishing crates" + echo "Target registry: $REGISTRY" + parity-publish apply -p -d + else + echo "Publishing crates to $REGISTRY..." + parity-publish apply -p + echo "Crates published successfully to $REGISTRY!" + fi diff --git a/scripts/release/replace-all-path-deps.sh b/scripts/release/replace-all-path-deps.sh index 21be034cfa9a5..36cc7e64bb142 100755 --- a/scripts/release/replace-all-path-deps.sh +++ b/scripts/release/replace-all-path-deps.sh @@ -14,8 +14,7 @@ find . -name "Cargo.toml" \ # Find and replace path dependencies with "workspace = true" awk ' BEGIN { in_section = 0 } - /^\[dependencies\]/ { in_section = 1; print; next } - /^\[dev-dependencies\]/ { in_section = 2; print; next } + /^\[.*dependencies\]/ { in_section = 1; print; next } /^\[.*\]/ { in_section = 0; print; next } {