Skip to content

Commit 8096f9b

Browse files
authored
ci: switch pub.dev auth to credentials file with refresh token (#3)
* chore: migrate package publishing from Artifactory to pub.dev Replaces Artifactory configs with pub.dev authentication via PUB_TOKEN, updates CI/CD to use `dart pub token add`, and removes old secrets. Also updates documentation to reflect the new publishing process, streamlining releases in the Dart/Flutter ecosystem. * ci: update pub.dev auth to use full credentials with auto-refresh Enables automatic token renewal in CI/CD by using the complete credentials file. Updates workflows accordingly and adds a guide on managing pub.dev credentials and token rotation best practices. * docs: add dependency management strategy and fix analysis warnings script
1 parent 4be230a commit 8096f9b

File tree

14 files changed

+1015
-376
lines changed

14 files changed

+1015
-376
lines changed

.github/SECRETS.md

Lines changed: 67 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,110 @@
11
# GitHub Secrets Configuration
22

3-
This document lists all the secrets and environment variables required for the CI/CD pipelines.
3+
This document describes the required secrets for the CI/CD pipeline.
44

55
## Required Secrets
66

7-
### Repository Secrets
8-
97
Configure these secrets in your GitHub repository settings (`Settings > Secrets and variables > Actions`):
108

11-
#### Artifactory Configuration
12-
- **`ARTIFACTORY_URL`** - URL of your artifactory instance (e.g., `https://your-company.jfrog.io/artifactory/api/pub/dart`)
13-
- **`ARTIFACTORY_USERNAME`** - Username for artifactory authentication
14-
- **`ARTIFACTORY_PASSWORD`** - Password or API key for artifactory authentication
9+
### pub.dev Configuration
10+
- **`PUB_CREDENTIALS`** - Complete credentials JSON file for pub.dev publishing (includes refresh token for auto-renewal)
1511

16-
#### Optional Notification Secrets
17-
- **`SLACK_WEBHOOK_URL`** - Slack webhook for release notifications (optional)
18-
- **`DISCORD_WEBHOOK_URL`** - Discord webhook for release notifications (optional)
12+
### Optional Notification Secrets
13+
- **`SLACK_WEBHOOK_URL`** - Webhook URL for Slack notifications (optional)
14+
- **`DISCORD_WEBHOOK_URL`** - Webhook URL for Discord notifications (optional)
1915

20-
### Environment Variables
16+
## Setting Up Secrets
2117

22-
These are automatically available in GitHub Actions:
18+
### 1. pub.dev Setup
2319

24-
- **`GITHUB_TOKEN`** - Automatically provided by GitHub Actions
25-
- **`GITHUB_ACTOR`** - Username of the person who triggered the workflow
26-
- **`GITHUB_REF`** - Branch or tag ref that triggered the workflow
20+
1. **Generate pub.dev token:**
21+
```bash
22+
# Login to pub.dev locally first
23+
dart pub login
24+
25+
# Get your credentials file
26+
cat ~/.pub-cache/credentials.json
27+
```
2728

28-
## Setting Up Secrets
29+
2. **Copy complete credentials:**
30+
- Copy the ENTIRE JSON content from the credentials.json file
31+
- Include the `refreshToken` for automatic token renewal
32+
- This is your `PUB_CREDENTIALS` value
2933

30-
### 1. Artifactory Setup
34+
3. **Add to GitHub:**
35+
- Go to repository Settings > Secrets and variables > Actions
36+
- Click "New repository secret"
37+
- Name: `PUB_CREDENTIALS`
38+
- Value: The complete JSON from step 2
3139

40+
### 2. Notification Setup (Optional)
41+
42+
#### Slack
3243
```bash
33-
# Example artifactory URL formats:
34-
# JFrog Cloud: https://your-company.jfrog.io/artifactory/api/pub/dart
35-
# Self-hosted: https://artifactory.your-company.com/artifactory/api/pub/dart
44+
# Create a Slack webhook in your workspace
45+
# Add the webhook URL as SLACK_WEBHOOK_URL secret
3646
```
3747

38-
### 2. GitHub Repository Settings
39-
40-
1. Go to your repository on GitHub
41-
2. Click on `Settings` tab
42-
3. Navigate to `Secrets and variables > Actions`
43-
4. Click `New repository secret`
44-
5. Add each secret with the exact name listed above
45-
46-
### 3. Testing Secrets
47-
48-
You can test if secrets are properly configured by running the manual release workflow with dry-run enabled.
48+
#### Discord
49+
```bash
50+
# Create a Discord webhook in your server
51+
# Add the webhook URL as DISCORD_WEBHOOK_URL secret
52+
```
4953

5054
## Security Best Practices
5155

52-
### Secret Management
53-
- Use API keys instead of passwords when possible
54-
- Rotate secrets regularly
55-
- Use least-privilege access for artifactory users
56+
- Use tokens with minimal required permissions
57+
- Rotate tokens regularly
5658
- Never log secret values in workflows
59+
- Use environment-specific secrets when possible
5760

58-
### Access Control
59-
- Limit repository access to trusted contributors
60-
- Use branch protection rules for main/develop branches
61-
- Require PR reviews for sensitive changes
61+
## Verification
6262

63-
### Monitoring
64-
- Monitor artifactory access logs
65-
- Set up alerts for failed releases
66-
- Review workflow logs regularly
63+
Test your setup:
64+
```bash
65+
# Dry run to test authentication
66+
melos publish --dry-run
67+
```
6768

6869
## Troubleshooting
6970

7071
### Common Issues
7172

72-
#### Artifactory Authentication Failed
73+
#### pub.dev Authentication Failed
7374
```
74-
Error: 401 Unauthorized
75+
Error: 401 Unauthorized when accessing https://pub.dartlang.org
7576
```
76-
**Solution:** Check `ARTIFACTORY_USERNAME` and `ARTIFACTORY_PASSWORD` are correct.
77+
**Solution:** Check that `PUB_CREDENTIALS` contains valid JSON with both accessToken and refreshToken.
7778

78-
#### Artifactory URL Not Found
79+
#### Token Expired
7980
```
80-
Error: Could not resolve host
81+
Error: Token has expired
8182
```
82-
**Solution:** Verify `ARTIFACTORY_URL` is correct and accessible.
83+
**Solution:** Generate a new token using `dart pub login` and update the secret.
8384

8485
#### Missing Permissions
8586
```
86-
Error: Resource not accessible by integration
87+
Error: Insufficient permissions to publish package
8788
```
88-
**Solution:** Ensure the repository has proper permissions and the `GITHUB_TOKEN` has write access.
89+
**Solution:** Ensure you have publisher permissions for the package on pub.dev.
8990

90-
### Debug Mode
91+
## Token Management
9192

92-
To enable debug logging in workflows, add this secret:
93-
- **`ACTIONS_RUNNER_DEBUG`** = `true`
93+
### Rotating Tokens
94+
1. Generate new token: `dart pub login`
95+
2. Update GitHub secret with new token
96+
3. Test with dry-run: `melos publish --dry-run`
9497

95-
## Workflow Permissions
98+
### Monitoring
99+
- Monitor pub.dev package dashboard
100+
- Set up alerts for failed releases
101+
- Review workflow logs regularly
96102

97-
The workflows require these permissions:
103+
## Package Publishing Process
98104

99-
```yaml
100-
permissions:
101-
contents: write # For creating commits and tags
102-
packages: write # For publishing packages
103-
pull-requests: write # For commenting on PRs
104-
```
105+
1. **Authentication**: GitHub Actions uses `PUB_TOKEN` to authenticate
106+
2. **Validation**: Packages are validated before publishing
107+
3. **Publishing**: Only changed packages are published
108+
4. **Verification**: Success/failure is reported in workflow logs
105109

106-
These are automatically configured in the workflow files.
110+
For more details, see the main [CI/CD documentation](../docs/CI-CD.md).

.github/workflows/ci-cd.yml

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -194,35 +194,26 @@ jobs:
194194
git push origin main
195195
git push origin --tags
196196
197-
- name: 📦 Publish to artifactory
197+
- name: 📦 Publish to pub.dev
198198
if: steps.check-changes.outputs.changed_packages > 0
199199
env:
200-
ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }}
201-
ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
202-
ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
200+
PUB_CREDENTIALS: ${{ secrets.PUB_CREDENTIALS }}
203201
run: |
204-
# Configure pub for artifactory
205-
if [ ! -z "$ARTIFACTORY_URL" ]; then
206-
echo "🏛️ Publishing to artifactory: $ARTIFACTORY_URL"
207-
208-
# Setup artifactory credentials
202+
# Setup pub.dev credentials for auto-refresh
203+
if [ -n "$PUB_CREDENTIALS" ]; then
204+
echo "🔐 Setting up pub.dev credentials with auto-refresh..."
209205
mkdir -p ~/.pub-cache
210-
cat > ~/.pub-cache/credentials.json << EOF
211-
{
212-
"accessToken": null,
213-
"refreshToken": null,
214-
"tokenEndpoint": null,
215-
"scopes": null,
216-
"expiration": null
217-
}
218-
EOF
219-
220-
# Publish packages to artifactory
221-
melos publish --no-dry-run --yes || echo "⚠️ Some packages may have failed to publish"
206+
echo "$PUB_CREDENTIALS" > ~/.pub-cache/credentials.json
207+
echo "✅ Credentials configured with refresh token"
222208
else
223-
echo "⚠️ Artifactory not configured, skipping publish"
209+
echo "⚠️ PUB_CREDENTIALS not configured, skipping publish"
210+
exit 1
224211
fi
225212
213+
# Publish packages (dart pub will auto-refresh token if needed)
214+
echo "📦 Publishing packages to pub.dev..."
215+
melos publish --no-dry-run --yes || echo "⚠️ Some packages may have failed to publish"
216+
226217
- name: 📋 Create GitHub release
227218
if: steps.check-changes.outputs.changed_packages > 0
228219
uses: actions/create-release@v1

.github/workflows/manual-release.yml

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -167,34 +167,26 @@ jobs:
167167
git add CHANGELOG.md
168168
git commit -m "docs: update changelog for ${{ github.event.inputs.release_type }} release" || echo "No changelog changes to commit"
169169
170-
- name: 📦 Publish to artifactory
170+
- name: 📦 Publish to pub.dev
171171
if: github.event.inputs.dry_run == 'false'
172172
env:
173-
ARTIFACTORY_URL: ${{ secrets.ARTIFACTORY_URL }}
174-
ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
175-
ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
173+
PUB_CREDENTIALS: ${{ secrets.PUB_CREDENTIALS }}
176174
run: |
177-
if [ ! -z "$ARTIFACTORY_URL" ]; then
178-
echo "🏛️ Publishing to artifactory: $ARTIFACTORY_URL"
179-
180-
# Setup artifactory credentials
175+
# Setup pub.dev credentials for auto-refresh
176+
if [ -n "$PUB_CREDENTIALS" ]; then
177+
echo "🔐 Setting up pub.dev credentials with auto-refresh..."
181178
mkdir -p ~/.pub-cache
182-
cat > ~/.pub-cache/credentials.json << EOF
183-
{
184-
"accessToken": null,
185-
"refreshToken": null,
186-
"tokenEndpoint": null,
187-
"scopes": null,
188-
"expiration": null
189-
}
190-
EOF
191-
192-
# Publish packages
193-
melos publish --no-dry-run --yes
179+
echo "$PUB_CREDENTIALS" > ~/.pub-cache/credentials.json
180+
echo "✅ Credentials configured with refresh token"
194181
else
195-
echo "⚠️ Artifactory not configured, skipping publish"
182+
echo "⚠️ PUB_CREDENTIALS not configured, skipping publish"
183+
exit 1
196184
fi
197185
186+
# Publish packages (dart pub will auto-refresh token if needed)
187+
echo "📦 Publishing packages to pub.dev..."
188+
melos publish --no-dry-run --yes
189+
198190
- name: 📋 Create release summary
199191
if: github.event.inputs.dry_run == 'false'
200192
run: |

.github/workflows/pr-checks.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ jobs:
301301
echo "When this PR is merged to main:"
302302
echo "- Packages will be automatically versioned"
303303
echo "- Changelogs will be updated"
304-
echo "- Packages will be published to artifactory"
304+
echo "- Packages will be published to pub.dev"
305305
echo "- GitHub releases will be created"
306306
307307
- name: ❌ Checks failed

0 commit comments

Comments
 (0)