Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Configure CI/CD pipelines for Adobe integrations with GitHub Actions, including OAuth credential injection, PDF Services testing, Firefly API smoke tests, and secret scanning for Adobe credential patterns. Trigger with phrases like "adobe CI", "adobe GitHub Actions", "adobe automated tests", "CI adobe", "adobe pipeline".
.claude/skills/jeremylongshore-adobe-ci-integration/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 38% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 53% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 35% | 0% |
| case-05 | ✗→✓ | ▲ Improved | -9% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 97% | 0% |
Set up CI/CD pipelines for Adobe API integrations with proper credential management, unit/integration test separation, and secret scanning for Adobe-specific credential patterns.
bash# Set OAuth Server-to-Server credentials gh secret set ADOBE_CLIENT_ID --body "your-ci-client-id" gh secret set ADOBE_CLIENT_SECRET --body "your-ci-client-secret" gh secret set ADOBE_SCOPES --body "openid,AdobeID,firefly_api"
yaml# .github/workflows/adobe-integration.yml name: Adobe Integration Tests on: push: branches: [main] pull_request: branches: [main] jobs: unit-tests: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - run: npm ci - run: npm test -- --coverage # Unit tests run with mocked Adobe APIs — no credentials needed secret-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Scan for Adobe credentials run: | FOUND=0 # Adobe OAuth client secrets start with p8_ if grep -rE "p8_[A-Za-z0-9_-]{20,}" --include="*.ts" --include="*.js" --include="*.py" --include="*.json" . 2>/dev/null; then echo "::error::Adobe client_secret pattern found in source" FOUND=1 fi # Adobe IMS access tokens if grep -rE "eyJ[A-Za-z0-9_-]{50,}" --include="*.ts" --include="*.js" . 2>/dev/null; then echo "::warning::Potential Adobe access token found" fi exit $FOUND integration-tests: needs: [unit-tests, secret-scan] runs-on: ubuntu-latest # Only run on main branch (uses real API credentials) if: github.ref == 'refs/heads/main' env: ADOBE_CLIENT_ID: ${{ secrets.ADOBE_CLIENT_ID }} ADOBE_CLIENT_SECRET: ${{ secrets.ADOBE_CLIENT_SECRET }} ADOBE_SCOPES: ${{ secrets.ADOBE_SCOPES }} steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - run: npm ci - name: Verify Adobe OAuth credentials run: | HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \ 'https://ims-na1.adobelogin.com/ims/token/v3' \ -d "client_id=${ADOBE_CLIENT_ID}&client_secret=${ADOBE_CLIENT_SECRET}&grant_type=client_credentials&scope=${ADOBE_SCOPES}") if [ "$HTTP_CODE" != "200" ]; then echo "::error::Adobe OAuth token generation failed (HTTP $HTTP_CODE)" exit 1 fi echo "Adobe credentials verified" - name: Run integration tests run: npm run test:integration timeout-minutes: 5
typescript// tests/integration/adobe-api.test.ts import { describe, it, expect } from 'vitest'; import { getAccessToken } from '../../src/adobe/client'; const hasCredentials = !!( process.env.ADOBE_CLIENT_ID && process.env.ADOBE_CLIENT_SECRET ); describe.skipIf(!hasCredentials)('Adobe API Integration', () => { it('should generate valid OAuth access token', async () => { const token = await getAccessToken(); expect(token).toBeTruthy(); expect(token.length).toBeGreaterThan(100); }, 10_000); it('should call Firefly API health endpoint', async () => { const token = await getAccessToken(); const response = await fetch('https://firefly-api.adobe.io/v3/images/generate', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'x-api-key': process.env.ADOBE_CLIENT_ID!, 'Content-Type': 'application/json', }, body: JSON.stringify({ prompt: 'solid blue square', n: 1, size: { width: 512, height: 512 }, }), }); // 200 = success, 429 = rate limited (acceptable in CI) expect([200, 429]).toContain(response.status); }, 30_000); });
yaml# .github/workflows/release.yml on: push: tags: ['v*'] jobs: release: runs-on: ubuntu-latest env: ADOBE_CLIENT_ID: ${{ secrets.ADOBE_CLIENT_ID_PROD }} ADOBE_CLIENT_SECRET: ${{ secrets.ADOBE_CLIENT_SECRET_PROD }} ADOBE_SCOPES: ${{ secrets.ADOBE_SCOPES }} steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: '20' } - run: npm ci - run: npm test - name: Verify Adobe production credentials run: npm run test:integration - run: npm run build - run: npm publish
| Issue | Cause | Solution | |-------|-------|----------| | invalid_client in CI | Wrong secret value | Re-set with gh secret set | | Integration test 429 | Rate limited | Accept 429 as valid CI result | | Secret scan false positive | Test fixture data | Exclude test directories from scan | | Timeout on Firefly test | API latency | Increase vitest timeout to 30s |
Start with the smallest applicable command or code example already provided in this guide, using a non-production Adobe environment and credentials. Confirm the documented response or validation result before applying the pattern to production.
For deployment patterns, see adobe-deploy-integration.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 15,798 | 41,665 | +164% | 1 | 1 | 0% | 3,065 | 4,234 | +38% | 0 | 0 | — |
case-02 | fail→pass | 18,262 | 15,228 | -17% | 1 | 1 | 0% | 3,441 | 5,273 | +53% | 0 | 0 | — |
case-03 | fail→fail | 16,082 | 8,786 | -45% | 1 | 1 | 0% | 3,041 | 3,589 | +18% | 0 | 0 | — |
case-04 | fail→pass | 13,847 | 5,148 | -63% | 1 | 1 | 0% | 2,009 | 2,717 | +35% | 0 | 0 | — |
case-05 | fail→pass | 14,323 | 2,686 | -81% | 1 | 1 | 0% | 2,509 | 2,280 | -9% | 0 | 0 | — |
case-06 | pass→pass | 13,248 | 3,889 | -71% | 1 | 1 | 0% | 2,170 | 2,448 | +13% | 0 | 0 | — |
case-07 | pass→fail | 20,407 | 13,027 | -36% | 1 | 1 | 0% | 3,304 | 4,191 | +27% | 0 | 0 | — |
case-08 | fail→pass | 6,525 | 3,053 | -53% | 1 | 1 | 0% | 1,131 | 2,223 | +97% | 0 | 0 | — |
case-09 | pass→pass | 6,229 | 3,892 | -38% | 1 | 1 | 0% | 1,149 | 2,328 | +103% | 0 | 0 | — |
case-10 | fail→pass | 10,869 | 2,205 | -80% | 1 | 1 | 0% | 1,736 | 2,096 | +21% | 0 | 0 | — |
case-20 | pass→pass | 19,597 | 18,882 | -4% | 1 | 1 | 0% | 4,035 | 6,072 | +50% | 0 | 0 | — |
case-11 | pass→pass | 6,855 | 3,889 | -43% | 1 | 1 | 0% | 1,133 | 2,239 | +98% | 0 | 0 | — |
case-12 | fail→pass | 12,421 | 3,557 | -71% | 1 | 1 | 0% | 1,943 | 2,430 | +25% | 0 | 0 | — |
case-13 | fail→pass | 14,609 | 8,182 | -44% | 1 | 1 | 0% | 2,411 | 3,213 | +33% | 0 | 0 | — |
case-14 | pass→pass | 14,361 | 9,490 | -34% | 1 | 1 | 0% | 2,122 | 3,518 | +66% | 0 | 0 | — |
case-15 | pass→pass | 11,456 | 4,218 | -63% | 1 | 1 | 0% | 2,079 | 2,554 | +23% | 0 | 0 | — |
case-16 | pass→pass | 10,649 | 3,181 | -70% | 1 | 1 | 0% | 1,821 | 2,306 | +27% | 0 | 0 | — |
case-17 | fail→pass | 5,277 | 18,669 | +254% | 1 | 1 | 0% | 954 | 2,246 | +135% | 0 | 0 | — |
case-18 | fail→pass | 14,429 | 6,596 | -54% | 1 | 1 | 0% | 2,303 | 2,980 | +29% | 0 | 0 | — |
case-19 | fail→pass | 15,978 | 1,724 | -89% | 1 | 1 | 0% | 2,557 | 1,992 | -22% | 0 | 0 | — |
case-21 | pass→pass | 13,875 | 14,665 | +6% | 1 | 1 | 0% | 2,504 | 4,360 | +74% | 0 | 0 | — |
case-22 | pass→pass | 23,538 | 17,950 | -24% | 1 | 1 | 0% | 4,695 | 5,650 | +20% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +45 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 8/13/2026 | +41% |
Other measured skills in the registry, with their headline benchmark lift.