Generated banner for Provider Upgrade
Generated logo for Provider Upgrade

Provider Upgrade

PulumiOfficialPublished by Pulumi

  • Skill
  • Workflow
  • Cloud and DevOps
  • Apache-2.0
  • No issues found

From the author

Upgrade any Pulumi provider to a newer version and reconcile the resulting diff. Use when users want to upgrade or update a provider (including editing package.json, requirements.txt, pyproject.toml, go.mod, or Pulumi.yaml to bump a provider SDK), check for breaking changes before or during an upgrade, fix resources that broke after a provider upgrade, or resolve unexpected replacements, creates, or deletes in a post-upgrade preview, including pulumi-gcp v10 errors such as a missing gcp.notebooks or gcp.iap.Brand type or a required secretDataWoVersion. Applies to all providers (aws, azure-native, gcp, kubernetes, aws-native, cloudflare, datadog, etc.) — not just Tier 1. Do NOT use for querying which stacks use what package versions; use skill `package-usage` for cross-stack audits. Do NOT use for general infrastructure tasks.
— the description by Pulumi

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a rigorous, step-by-step procedure for upgrading Pulumi providers. It emphasizes that an upgrade is a translation of existing infrastructure intent to a new API version, rather than a change to the infrastructure itself. The workflow centers on a core loop of bumping dependencies, running previews with specific flags, and performing a detailed 'Diff Checkpoint' to categorize and resolve any discrepancies. It includes specific guidance for handling breaking changes, managing state, and ensuring that no real-world infrastructure is unintentionally destroyed during the upgrade process.

What it does

  • Guides the user through bumping provider dependencies across various languages.
  • Provides a structured 'Diff Checkpoint' to categorize and resolve resource changes.
  • Offers strategies for handling Category A (code-related) and Category B (provider-related) diffs.
  • Includes safety procedures for major version upgrades, such as pulumi-gcp v10.
  • Ensures all remaining diffs are documented with authoritative sources before PR creation.
  • Prevents accidental infrastructure destruction by mandating manual state management for removed resources.

When to use it

  • When you need to upgrade a Pulumi provider to a newer version.
  • When a provider upgrade results in unexpected resource replacements, creates, or deletes.
  • When you need to resolve breaking changes introduced by a major provider version bump.
  • When you need to fix resources that have become misaligned after a provider update.

Advantages

  • Minimizes the risk of accidental infrastructure destruction.
  • Provides a clear, repeatable process for handling complex provider migrations.
  • Ensures that infrastructure intent remains consistent across provider versions.
  • Forces evidence-based resolution of diffs rather than relying on assumptions.
  • Reduces the likelihood of regressions by promoting minimal, targeted code changes.

Usage examples

“Help me upgrade the Pulumi GCP provider from v9 to v10.”
The agent will initiate the v9-to-v10 migration workflow, starting with a version gate check, a clean baseline verification, and a state scan to identify high-risk resources before any code changes are made.
“I updated my AWS provider and now my S3 bucket shows an update in the preview. What should I do?”
The agent will guide you through the Diff Checkpoint to determine if the update is a result of your code changes (Category A) or a provider-level change (Category B), and help you decide whether to fix the code or document the diff as a no-op.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/pulumi/provider-upgrade/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip provider-upgrade.zip -d .agents/skills

Documentation by Pulumi

Upgrading Pulumi Providers

The Principle

A provider upgrade is a translation, not a change request.

The user's infrastructure intent hasn't changed - they still want the same bucket, the same function, the same cluster. What changed is how the provider's API expresses that intent. Your job is to translate their existing code into the new API so that Pulumi sees no difference between what the code says and what already exists.

There are four layers to keep in mind:

  1. User intent - what the user wants in the cloud (unchanged during an upgrade)

  2. Code - how the program expresses that intent using the provider API (may need updating)

  3. Pulumi state - Pulumi's stored representation of what exists (may need reconciliation)

  4. Real cloud - the actual infrastructure (should not change during an upgrade)

During an upgrade, layers 2 and 3 may need to change so that they continue to correctly represent the unchanged layers 1 and 4.

A correct translation produces zero diff. The Pulumi engine doesn't have a concept of "upgrade" - it just compares goal state (your code) against actual state (the state file) and reconciles. If the translation is correct, those two states match and nothing happens. If you see a diff, either your translation is wrong, or something beyond a code change is needed (import, alias, manual step). In all cases, the diff is a problem to solve, not a consequence to accept.

The Core Loop

flowchart TD
    A[Bump version] --> B[Run preview with env vars]
    B --> C{Clean?}
    C -->|Yes| D[Create PR]
    C -->|No| E[Diff Checkpoint: categorize every diff]
    E --> F{Any Category A?}
    F -->|Yes| G[Fix wrong translations]
    G --> B
    F -->|No| H{Any Category B?}
    H -->|Yes| I[Investigate with toolbox]
    I --> J[Fix or document]
    J --> B
    H -->|No| D
  1. Bump the provider dependency

  2. Preview with required CLI flags

  3. Diff Checkpoint - categorize every non-same resource (see next section)

  4. Fix Category A - code changes that didn't produce same

  5. Investigate Category B - diffs on resources you didn't change

  6. Repeat until clean or remaining diffs are fully investigated

  7. Create PR with upgrade summary


The Diff Checkpoint

This is the most important section. Run this after EVERY preview.

For each non-same resource, answer one question: "Did any of my code changes affect this resource - directly or indirectly?"

"Directly" means you edited the resource block itself. "Indirectly" means you changed something that feeds into this resource - a shared variable, an output from another resource, a helper function, a default value, or a resource that this one depends on. If your changes could have altered what Pulumi computes for this resource, it's Category A.

Then follow the category that applies.

Category A: I changed code for this resource

Your code change was supposed to translate the same intent into the new API. If the resource shows same, your translation is correct. If it shows anything else, your translation is wrong. Not "the diff is expected because I changed the code" - if the change were semantically equivalent, there would be no diff.

I modified an existing resource and it shows update:

Your rename, restructure, or value adjustment changed the meaning, not just the syntax. The resource would show same if the old and new code compiled to the same goal state. The update means they don't.

Ask yourself: "If this rename were truly equivalent, the resource would show same. It doesn't. What is semantically different between my old code and my new code?"

Common causes: the new property name maps to a different underlying field; the value shape changed and your conversion lost or added information; a default value changed in the new version and you need to explicitly set the old value; additional properties now appear in the diff because the new provider version tracks fields it didn't before (these need to be set explicitly to match the current state).

If the update includes properties you didn't change - new fields appearing, type normalizations (string->number), additional defaults - that's the provider changing what it tracks. But if the diff is there, pulumi up WILL send those values to the cloud API. Don't assume they're no-ops. Investigate each changed property.

I added a new resource block and it shows create:

During an upgrade, a new resource block almost always represents infrastructure that already exists in the cloud. The old provider managed it implicitly (as part of another resource); the new provider needs an explicit resource. But the cloud object is already there. Pulumi wants to create NEW infrastructure - that's not what you want.

The fix is import, not create. Tell Pulumi to adopt the existing cloud resource.

Ask yourself: "What cloud object does this new resource represent? Does it already exist? How was it managed before the upgrade?"

// Wrong - creates duplicate infrastructure
const stage = new aws.apigateway.Stage("prodStage", { ... });

// Right - adopts the existing resource
const stage = new aws.apigateway.Stage("prodStage", { ... }, {
    import: "<rest-api-id>/prod",  // import ID format varies by resource type
});

I removed a resource block and it shows delete:

A delete in the preview means pulumi up will call the provider's Delete API to destroy or unconfigure this cloud resource. This is real destruction - not just state cleanup. The cloud infrastructure still exists and is almost certainly still needed.

This is different from pulumi state delete, which removes the resource from Pulumi's tracking WITHOUT calling the provider's API. When a resource type is removed in a new provider version, the correct approach is:

  1. pulumi state delete '<urn>' - manual step, removes from tracking only

  2. Add replacement resources (if any) with imports - adopts the cloud state under new types

  3. Verify with preview

Do NOT leave a delete in the preview and proceed to PR creation. A delete that runs via pulumi up will destroy real infrastructure. If the resource must be removed from state, document it as a manual step for the user.

Ask yourself: "What cloud infrastructure does this resource manage? If pulumi up runs this delete, what gets destroyed or unconfigured?"

Category B: I didn't change code for this resource

This diff was not caused by your code changes. It comes from the provider version change itself - a different default, a changed state representation, or a behavioral difference. Read references/diagnostic-toolbox.md and investigate.

These diffs might be:

  • Fixable with code - set an explicit value for a changed default, add an alias

  • A documented no-op - the upgrade guide says it resolves on pulumi up without affecting real infrastructure. This classification REQUIRES a citation from the upgrade guide or provider documentation. Your own judgment that "this looks like a no-op" is not sufficient - the user is trusting you to distinguish real infrastructure changes from artifacts, and getting it wrong means unexpected changes to their cloud.

  • Requiring manual steps - state removal + reimport, documented for the user

  • Unknown - present what you've found to the user and ask for guidance

Category C: Provider version bump

An update on pulumi:providers:{name} showing only a version change is the one expected diff. Verify no other properties changed on the provider resource.

After categorizing

Completeness check: Every resource in the preview that shows any non-same state must appear in your checkpoint - including resources with [diff: ...] annotations, even if they don't have an explicit create/update/delete marker. If you didn't list it, your checkpoint is incomplete. Go back and categorize the missing resources.

Evidence requirement for accepted diffs: If you want to accept any diff as "OK" (not fix it), you need evidence - whether it's Category A or Category B. "I believe the API treats these equivalently" or "this looks like state reconciliation" is not evidence. Acceptable evidence: the upgrade guide documents it, a GitHub issue confirms it, or the provider documentation explains the behavior. If you can't find evidence, either fix the diff or flag it to the user.

Ordering: Fix all Category A issues before investigating Category B. Your code corrections will change the preview output, so investigating Category B diffs first wastes effort. Fix your own mistakes first, re-preview, then look at what remains.

No delete or replace in the final preview. If a delete or replace remains when you're ready to create a PR, stop. A delete means pulumi up will destroy cloud infrastructure. A replace means it will destroy and recreate. These are never acceptable as "remaining diffs" - they must be resolved (via code fix, alias, or documented manual steps) before proceeding.


Hard Rules

Required CLI flags

Use these flags when running preview. A preview without them can show false diffs (phantom tag removals, region additions) that aren't real. Don't interpret a preview that was run without them.

pulumi preview --refresh --run-program
  • --refresh refreshes actual cloud state before diffing.

  • --run-program runs the Pulumi program during refresh.

Don't chase deprecations

If something is deprecated but still works, leave it alone. Migrating to the replacement introduces risk for no benefit. A deprecation warning is acceptable - a diff is not.

// BAD: migrating deprecated-but-working properties introduces risk
new aws.s3.Bucket('bucket');
new aws.s3.BucketLogging('bucketLogging', {...});  // unnecessary migration

// GOOD: fix only the actual error, leave working code alone
new aws.s3.Bucket('bucket', {
  logging: {...},  // "loggings" renamed to "logging" - real breaking change
  website: {...},  // deprecated but works - don't touch
});
Be minimally invasive

Every line changed could introduce a regression. Prefer the smallest change that works.

Do not run pulumi up

Provider upgrades modify source code and need code review before deployment. PR -> review -> merge -> deploy via CI/CD.


Getting Started

1. Get version information

Determine the target version from the user's request, the Pulumi Registry, package manager metadata, or the repository's existing dependency constraints.

Default to the latest stable version if the user hasn't specified a target version. If the user asks which stacks or projects are affected, use skill package-usage or the best available package inventory tooling before making changes.

1a. Check for a provider-specific reference

Some major versions have breaking changes that destroy live resources if fixed in the wrong order, which preview alone does not reveal. If references/ has a file for this provider and target major (for example gcp-v10.md for pulumi-gcp to 10.x), read it now and follow its "Before the bump" section before step 2. For that upgrade it overrides the "Do not research breaking changes first" rule in step 3.

2. Update the dependency
  • TypeScript/JavaScript: npm install @pulumi/{provider}@^{version} or yarn add @pulumi/{provider}@^{version}

  • Python: Update pyproject.toml or requirements.txt with pulumi_{provider}>={version} (underscore, not hyphen), then install

  • Go: go get github.com/pulumi/pulumi-{provider}/sdk/v{major}@latest, update all import paths (e.g., v6 -> v7), run go mod tidy

  • .NET: dotnet add package Pulumi.{Provider} --version {version}

  • Java: Update pom.xml or build.gradle dependency version

  • YAML: Update provider version in resource options or provider configuration. See https://www.pulumi.com/docs/iac/languages-sdks/yaml/yaml-language-reference/#providers-and-provider-versions for examples.

After installing, check the actual installed version from the lockfile (package-lock.json, go.sum, etc.) - use these exact versions for schema-tools comparisons.

3. Run preview

Run pulumi preview --refresh --run-program immediately after updating the dependency. Do not research breaking changes first - many upgrades just work, especially minor versions.

If the preview is clean (only the provider version bump), create a PR.


Preview Progress

Preview can fail on the first error and hide others. Fixing one error often reveals new errors. This is normal progress, not a sign that fixes are making things worse.

  • New or different errors -> progress, continue

  • Error set shrank -> progress, continue

  • Same error persists -> your fix didn't work, try a different approach

  • No errors but diffs -> run the diff checkpoint


Upgrade Summary

Once the preview is clean (or as clean as possible), present the summary:

## Upgrade Summary: {provider} v{current} -> v{target}

### Code Changes
| File | Change | Why it preserves intent |
|------|--------|------------------------|
| package.json | Version bump | - |
| index.ts:15 | loggings -> logging | Property renamed, same underlying field |

### Preview Result
All resources show `same` except provider version bump.
{Or: N resources show diffs - see below}

### Remaining Diffs (if any)
| Resource | Operation | What happens on `pulumi up` | Risk | Source |
|----------|-----------|---------------------------|------|--------|
| aws:s3:Bucket (myBucket) | update (-tags) | No-op, state reconciles | None | AWS v7 guide section 3.2 |

Every remaining diff MUST cite an authoritative source (upgrade guide, provider docs,
upstream GitHub issue). "I believe this is expected" is not a source.

### Manual Steps Required (if any)
1. `pulumi state delete '<urn>'` - remove old type binding
2. `pulumi import <type> <name> <id>` - adopt under new type
3. `pulumi preview --refresh --run-program` - verify clean

### Deprecation Warnings (no action taken)
- List deprecated-but-working code left intentionally

If the preview is clean (or all remaining diffs are documented no-ops with cited sources), create a pull request. If unresolved diffs remain, present the summary as an exception report and ask the user how they'd like to proceed before creating a PR.


References

  • references/diagnostic-toolbox.md - upgrade guides, schema-tools (install, run, interpret output), stack state inspection, SDK types, GitHub issues. Read when investigating Category B diffs.

  • references/gcp-v10.md - every pulumi-gcp v10 breaking change with state scan, grep patterns, fix order and risk. Read before bumping pulumi-gcp to 10.x (see step 1a).

Files

LICENSE

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs Node.js

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
Pulumi
Publisher
Pulumi (Official)
Source
pulumi/agent-skills · pulumi/skills/provider-upgrade · commit 82f222a
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Pulumi or Pulumi.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download provider-upgrade.zip