|
| 1 | +--- |
| 2 | +name: AWS API MCP Server - Upgrade AWS CLI Version |
| 3 | +description: | |
| 4 | + This workflow upgrades the AWS CLI version in src/aws-api-mcp-server using uv upgrade |
| 5 | + and creates a pull request with the changes. |
| 6 | +on: |
| 7 | + workflow_dispatch: |
| 8 | + schedule: |
| 9 | + - cron: '0 5 * * *' # Daily at 6 AM Amsterdam time (UTC+1) |
| 10 | +env: |
| 11 | + BOT_USER_EMAIL: ${{ vars.BOT_USER_EMAIL || '[email protected]' }} |
| 12 | + BOT_USER_NAME: ${{ vars.BOT_USER_NAME || 'awslabs-mcp' }} |
| 13 | +permissions: |
| 14 | + actions: none |
| 15 | + attestations: none |
| 16 | + checks: none |
| 17 | + contents: none |
| 18 | + deployments: none |
| 19 | + discussions: none |
| 20 | + id-token: none |
| 21 | + issues: none |
| 22 | + models: none |
| 23 | + packages: none |
| 24 | + pages: none |
| 25 | + pull-requests: none |
| 26 | + repository-projects: none |
| 27 | + security-events: none |
| 28 | + statuses: none |
| 29 | +jobs: |
| 30 | + upgrade-awscli: |
| 31 | + name: Upgrade AWS CLI Version |
| 32 | + runs-on: ubuntu-latest |
| 33 | + timeout-minutes: 10 |
| 34 | + permissions: |
| 35 | + contents: write |
| 36 | + pull-requests: write |
| 37 | + steps: |
| 38 | + - name: Checkout repository |
| 39 | + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 |
| 40 | + with: |
| 41 | + token: ${{ secrets.BOT_GITHUB_TOKEN }} |
| 42 | + - name: Install uv |
| 43 | + uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0 |
| 44 | + - name: Check and upgrade AWS CLI version |
| 45 | + id: upgrade |
| 46 | + working-directory: src/aws-api-mcp-server |
| 47 | + run: | |
| 48 | + set -euo pipefail |
| 49 | +
|
| 50 | + # Get current installed version |
| 51 | + CURRENT_VERSION=$(uv run python -c "from importlib.metadata import version; print(version('awscli'))") |
| 52 | + echo "::debug::Current AWS CLI version: $CURRENT_VERSION" |
| 53 | +
|
| 54 | + # Get latest version from PyPI |
| 55 | + LATEST_VERSION=$(uv run --no-project python -c "import urllib.request, json; print(json.loads(urllib.request.urlopen('https://pypi.org/pypi/awscli/json').read())['info']['version'])") |
| 56 | + echo "::debug::Latest AWS CLI version from PyPI: $LATEST_VERSION" |
| 57 | +
|
| 58 | + # Set version outputs |
| 59 | + echo "current-version=$CURRENT_VERSION" >> $GITHUB_OUTPUT |
| 60 | + echo "latest-version=$LATEST_VERSION" >> $GITHUB_OUTPUT |
| 61 | +
|
| 62 | + # Compare versions |
| 63 | + if [[ "$CURRENT_VERSION" == "$LATEST_VERSION" ]]; then |
| 64 | + echo "has-changes=false" >> $GITHUB_OUTPUT |
| 65 | + echo "::notice::AWS CLI is already up to date (version $CURRENT_VERSION)" |
| 66 | + else |
| 67 | + echo "has-changes=true" >> $GITHUB_OUTPUT |
| 68 | + echo "::notice::Upgrading AWS CLI from $CURRENT_VERSION to $LATEST_VERSION" |
| 69 | +
|
| 70 | + # Remove existing awscli dependency |
| 71 | + echo "::debug::Removing existing awscli dependency" |
| 72 | + uv remove awscli |
| 73 | +
|
| 74 | + # Add new version with exact pinning |
| 75 | + echo "::debug::Adding awscli==$LATEST_VERSION" |
| 76 | + uv add "awscli==$LATEST_VERSION" |
| 77 | +
|
| 78 | + # Sync dependencies |
| 79 | + echo "::debug::Syncing dependencies" |
| 80 | + uv sync |
| 81 | +
|
| 82 | + echo "::debug::AWS CLI upgrade completed" |
| 83 | + fi |
| 84 | + - name: Create upgrade branch |
| 85 | + if: steps.upgrade.outputs.has-changes == 'true' |
| 86 | + id: create-branch |
| 87 | + run: | |
| 88 | + set -euo pipefail |
| 89 | +
|
| 90 | + LATEST_VERSION="${{ steps.upgrade.outputs.latest-version }}" |
| 91 | + UPGRADE_BRANCH="upgrade/aws-api-mcp-awscli-v$LATEST_VERSION" |
| 92 | +
|
| 93 | + echo "::debug::Creating upgrade branch: $UPGRADE_BRANCH" |
| 94 | +
|
| 95 | + # Configure git user |
| 96 | + git config --local user.email "${{ env.BOT_USER_EMAIL }}" |
| 97 | + git config --local user.name "${{ env.BOT_USER_NAME }}" |
| 98 | +
|
| 99 | + # Create and push branch |
| 100 | + git checkout -b "$UPGRADE_BRANCH" |
| 101 | + git push --set-upstream origin "$UPGRADE_BRANCH" |
| 102 | +
|
| 103 | + # Verify branch was created |
| 104 | + if ! git ls-remote --heads origin "$UPGRADE_BRANCH" | grep -q "$UPGRADE_BRANCH"; then |
| 105 | + echo "::error::Failed to verify branch creation: $UPGRADE_BRANCH" >&2 |
| 106 | + exit 1 |
| 107 | + fi |
| 108 | +
|
| 109 | + echo "upgrade-branch=$UPGRADE_BRANCH" >> $GITHUB_OUTPUT |
| 110 | + echo "::debug::Successfully created upgrade branch: $UPGRADE_BRANCH" |
| 111 | + - name: Configure Git and GPG securely |
| 112 | + if: steps.upgrade.outputs.has-changes == 'true' |
| 113 | + env: |
| 114 | + GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} |
| 115 | + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} |
| 116 | + GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }} |
| 117 | + run: | |
| 118 | + set -euo pipefail # SECURITY: Strict error handling |
| 119 | +
|
| 120 | + # Create secure temporary directory for GPG |
| 121 | + export GNUPGHOME=$(mktemp -d) |
| 122 | + chmod 700 "$GNUPGHOME" |
| 123 | + echo "GNUPGHOME=$GNUPGHOME" >> $GITHUB_ENV |
| 124 | +
|
| 125 | + echo "::debug::Setting up secure GPG environment" |
| 126 | +
|
| 127 | + # Configure git user |
| 128 | + git config --local user.email "${{ env.BOT_USER_EMAIL }}" |
| 129 | + git config --local user.name "${{ env.BOT_USER_NAME }}" |
| 130 | +
|
| 131 | + # Import GPG key without exposing secrets in command line |
| 132 | + echo "$GPG_PRIVATE_KEY" | gpg --batch --import --quiet |
| 133 | + echo "$GPG_KEY_ID:6:" | gpg --import-ownertrust --quiet |
| 134 | +
|
| 135 | + # Configure git GPG settings |
| 136 | + git config --global user.signingkey "$GPG_KEY_ID" |
| 137 | + git config --global commit.gpgsign true |
| 138 | + git config --global tag.gpgsign true |
| 139 | +
|
| 140 | + # Test GPG functionality |
| 141 | + echo "test" | gpg --batch --yes --passphrase-fd 0 --pinentry-mode loopback \ |
| 142 | + --sign --armor --local-user "$GPG_KEY_ID" <<< "$GPG_PASSPHRASE" > /dev/null |
| 143 | +
|
| 144 | + echo "::debug::GPG configuration completed successfully" |
| 145 | + - name: Commit and push changes |
| 146 | + if: steps.upgrade.outputs.has-changes == 'true' |
| 147 | + env: |
| 148 | + GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }} |
| 149 | + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} |
| 150 | + run: | |
| 151 | + set -euo pipefail |
| 152 | + echo "::debug::Committing changes" |
| 153 | +
|
| 154 | + # Add only the source directory |
| 155 | + git add src/aws-api-mcp-server/ |
| 156 | +
|
| 157 | + # Cache GPG signature |
| 158 | + echo "commit" | gpg --batch --yes --passphrase-fd 0 --pinentry-mode loopback \ |
| 159 | + --sign --armor --local-user "$GPG_KEY_ID" <<< "$GPG_PASSPHRASE" > /dev/null |
| 160 | +
|
| 161 | + # Create signed commit |
| 162 | + git commit -m "chore(aws-api-mcp-server): upgrade AWS CLI to v${{ steps.upgrade.outputs.latest-version }}" --sign |
| 163 | +
|
| 164 | + # Pull with rebase to maintain linear history |
| 165 | + git pull --rebase origin "${{ steps.create-branch.outputs.upgrade-branch }}" |
| 166 | +
|
| 167 | + # Push changes |
| 168 | + git push origin "${{ steps.create-branch.outputs.upgrade-branch }}" |
| 169 | +
|
| 170 | + echo "::debug::Successfully committed and pushed changes" |
| 171 | + - name: Create pull request |
| 172 | + if: steps.upgrade.outputs.has-changes == 'true' |
| 173 | + env: |
| 174 | + GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }} |
| 175 | + run: | |
| 176 | + set -euo pipefail |
| 177 | +
|
| 178 | + UPGRADE_BRANCH="${{ steps.create-branch.outputs.upgrade-branch }}" |
| 179 | + BASE_BRANCH="${{ github.ref_name }}" |
| 180 | +
|
| 181 | + echo "::debug::Creating PR from $UPGRADE_BRANCH to $BASE_BRANCH" |
| 182 | +
|
| 183 | + # Validate branch names |
| 184 | + if [[ ! "$UPGRADE_BRANCH" =~ ^upgrade/aws-api-mcp-awscli-v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then |
| 185 | + echo "::error::Invalid upgrade branch format: $UPGRADE_BRANCH" >&2 |
| 186 | + exit 1 |
| 187 | + fi |
| 188 | +
|
| 189 | + # Create PR with validated content |
| 190 | + PR_URL="$(gh pr create \ |
| 191 | + --base "$BASE_BRANCH" \ |
| 192 | + --head "$UPGRADE_BRANCH" \ |
| 193 | + --title "chore(aws-api-mcp-server): upgrade AWS CLI to v${{ steps.upgrade.outputs.latest-version }}" \ |
| 194 | + --label "aws-api-mcp" \ |
| 195 | + --body "# AWS CLI Version Upgrade |
| 196 | +
|
| 197 | + This PR upgrades the AWS CLI version in the aws-api-mcp-server package. |
| 198 | +
|
| 199 | + ## Changes |
| 200 | + * Updated AWS CLI from **v${{ steps.upgrade.outputs.current-version }}** to **v${{ steps.upgrade.outputs.latest-version }}** |
| 201 | +
|
| 202 | + ## Checklist |
| 203 | + - [ ] Dependencies have been upgraded |
| 204 | + - [ ] Lock file has been updated |
| 205 | + - [ ] Tests pass with new versions |
| 206 | +
|
| 207 | + ## Acknowledgment |
| 208 | + By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of the [project license](https://github.com/awslabs/mcp/blob/main/LICENSE).")" |
| 209 | +
|
| 210 | + echo "::debug::Successfully created pull request $PR_URL" |
| 211 | + echo "### :arrow_up: AWS CLI Upgrade Ready" >> $GITHUB_STEP_SUMMARY |
| 212 | + echo "Pull request $PR_URL created for [$UPGRADE_BRANCH](https://github.com/${{ github.repository }}/tree/$UPGRADE_BRANCH) branch" >> $GITHUB_STEP_SUMMARY |
| 213 | + - name: Secure GPG cleanup |
| 214 | + if: always() |
| 215 | + run: | |
| 216 | + set +e # Don't fail on cleanup errors |
| 217 | + echo "::debug::Performing secure cleanup" |
| 218 | + if [[ -n "${GNUPGHOME:-}" && -d "$GNUPGHOME" ]]; then |
| 219 | + rm -rf "$GNUPGHOME" |
| 220 | + echo "::debug::Cleaned up GPG directory" |
| 221 | + fi |
| 222 | + gpgconf --kill gpg-agent 2>/dev/null || true |
| 223 | + unset GPG_PRIVATE_KEY GPG_PASSPHRASE GPG_KEY_ID GNUPGHOME 2>/dev/null || true |
| 224 | + echo "::debug::Secure cleanup completed" |
0 commit comments