From shopify-pack
Configures GitHub Actions CI/CD pipelines for Shopify apps with linting, tests, integration testing, API version checks, and Shopify CLI deployment.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin shopify-packThis skill is limited to using the following tools:
Set up CI/CD pipelines for Shopify apps using GitHub Actions, including API version compatibility testing, Shopify CLI deployment, and extension validation.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
Set up CI/CD pipelines for Shopify apps using GitHub Actions, including API version compatibility testing, Shopify CLI deployment, and extension validation.
# .github/workflows/shopify-ci.yml
name: Shopify App CI
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
SHOPIFY_API_VERSION: "2024-10"
jobs:
lint-and-test:
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 run lint
- run: npm run typecheck
- run: npm test -- --coverage
env:
SHOPIFY_API_KEY: ${{ secrets.SHOPIFY_API_KEY }}
SHOPIFY_API_SECRET: ${{ secrets.SHOPIFY_API_SECRET }}
integration-test:
runs-on: ubuntu-latest
needs: lint-and-test
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- run: npm ci
- name: Run Shopify integration tests
run: npm run test:integration
env:
SHOPIFY_STORE: ${{ secrets.SHOPIFY_TEST_STORE }}
SHOPIFY_ACCESS_TOKEN: ${{ secrets.SHOPIFY_TEST_TOKEN }}
SHOPIFY_API_KEY: ${{ secrets.SHOPIFY_API_KEY }}
SHOPIFY_API_SECRET: ${{ secrets.SHOPIFY_API_SECRET }}
api-version-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check for deprecated API version
run: |
# Ensure we're not using an expired API version
VERSION=$(grep -r "apiVersion" src/ --include="*.ts" -h | head -1 | grep -oP '\d{4}-\d{2}')
echo "Using API version: $VERSION"
# Check if version is still supported
SUPPORTED=$(curl -sf -H "X-Shopify-Access-Token: ${{ secrets.SHOPIFY_TEST_TOKEN }}" \
"https://${{ secrets.SHOPIFY_TEST_STORE }}/admin/api/versions.json" \
| jq -r ".supported_versions[] | select(.handle == \"$VERSION\") | .supported")
if [ "$SUPPORTED" != "true" ]; then
echo "::warning::API version $VERSION is no longer supported!"
exit 1
fi
deploy:
runs-on: ubuntu-latest
needs: [lint-and-test, integration-test]
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npm ci
- run: npm run build
- name: Deploy with Shopify CLI
run: npx shopify app deploy --force
env:
SHOPIFY_CLI_PARTNERS_TOKEN: ${{ secrets.SHOPIFY_PARTNERS_TOKEN }}
# Store these in GitHub repository secrets
gh secret set SHOPIFY_API_KEY --body "your_api_key"
gh secret set SHOPIFY_API_SECRET --body "your_api_secret"
gh secret set SHOPIFY_TEST_STORE --body "your-dev-store.myshopify.com"
gh secret set SHOPIFY_TEST_TOKEN --body "shpat_test_token"
gh secret set SHOPIFY_PARTNERS_TOKEN --body "your_partners_cli_token"
// tests/integration/shopify.test.ts
import { describe, it, expect, beforeAll } from "vitest";
const SKIP = !process.env.SHOPIFY_ACCESS_TOKEN;
describe.skipIf(SKIP)("Shopify Integration", () => {
let client: any;
beforeAll(() => {
client = getGraphqlClient(process.env.SHOPIFY_STORE!);
});
it("should connect to store", async () => {
const response = await client.request("{ shop { name } }");
expect(response.data.shop.name).toBeTruthy();
});
it("should have required scopes", async () => {
const response = await client.request(`{
app { installation { accessScopes { handle } } }
}`);
const scopes = response.data.app.installation.accessScopes.map(
(s: any) => s.handle
);
expect(scopes).toContain("read_products");
expect(scopes).toContain("read_orders");
});
it("should query products within rate limits", async () => {
const response = await client.request(`{
products(first: 5) {
edges { node { id title } }
}
}`);
expect(response.extensions.cost.actualQueryCost).toBeLessThan(100);
});
});
| Issue | Cause | Solution |
|---|---|---|
SHOPIFY_PARTNERS_TOKEN invalid | Token expired | Regenerate at partners.shopify.com |
| Integration tests timeout | Rate limited | Add delays or use test store with Plus |
| API version check fails | Deprecated version | Update to latest supported version |
| Deploy fails | App config mismatch | Run shopify app config push first |
# Generate a CLI token for CI (no interactive login needed)
# Go to: partners.shopify.com > Settings > CLI tokens
# Create a new token and save as SHOPIFY_PARTNERS_TOKEN secret
For deployment patterns, see shopify-deploy-integration.