|
| 1 | +--- |
| 2 | +title: "Creating Package Revisions" |
| 3 | +type: docs |
| 4 | +weight: 3 |
| 5 | +description: "A step by step guide to creating a package revision in Porch" |
| 6 | +--- |
| 7 | + |
| 8 | +## Prerequisites |
| 9 | + |
| 10 | +- Porch deployed on a Kubernetes cluster [Setup Porch Guide]({{% relref "/docs/neo-porch/3_getting_started/installing-porch.md" %}}). |
| 11 | +- **Porchctl** CLI tool installed [Setup Porchctl Guide]({{% relref "/docs/neo-porch/3_getting_started/installing-porch.md" %}}). |
| 12 | +- A Git repository registered with Porch [Setup Repositories Guide]({{% relref "/docs/neo-porch/4_tutorials_and_how-tos/setting-up-repositories.md" %}}). |
| 13 | +- **Kubectl** configured to access your cluster. |
| 14 | + |
| 15 | +## Tutorial Overview |
| 16 | + |
| 17 | +You will learn how to: |
| 18 | + |
| 19 | +1. Initialize a new package revision |
| 20 | +2. Pull the package revision locally |
| 21 | +3. Modify the package revision contents |
| 22 | +4. Push changes back to Porch |
| 23 | +5. Propose the package revision for review |
| 24 | +6. Approve or reject the package revision |
| 25 | + |
| 26 | +{{% alert title="Understanding Terminology" color="primary" %}} |
| 27 | +In Porch, you work with **PackageRevisions** - there is no separate "Package" resource. When we say "package" colloquially, we're referring to a PackageRevision. The `rpkg` command stands for "revision package". |
| 28 | +{{% /alert %}} |
| 29 | + |
| 30 | +--- |
| 31 | + |
| 32 | +{{% alert title="Note" color="primary" %}} |
| 33 | +Please note the tutorial assumes a porch repository is initialized with the "porch-test" name. |
| 34 | +We recommended to use this for simpler copy pasting of commands otherwise replace any "porch-test" value with your repository's name in the below commands. |
| 35 | +{{% /alert %}} |
| 36 | + |
| 37 | +## Step 1: Initialize Your First Package Revision |
| 38 | + |
| 39 | +Create a new package revision in Porch using the `init` command: |
| 40 | + |
| 41 | +```bash |
| 42 | +porchctl rpkg init my-first-package \ |
| 43 | + --namespace=default \ |
| 44 | + --repository=porch-test \ |
| 45 | + --workspace=v1 \ |
| 46 | + --description="My first Porch package" |
| 47 | +``` |
| 48 | + |
| 49 | +**What this does:** |
| 50 | + |
| 51 | +- Creates a new PackageRevision named `my-first-package` |
| 52 | +- Places it in the `porch-test` repository |
| 53 | +- Uses `v1` as the workspace name (must be unique within this package) |
| 54 | +- Starts in `Draft` lifecycle state |
| 55 | + |
| 56 | + |
| 57 | + |
| 58 | +**Verify the package revision was created:** |
| 59 | + |
| 60 | +```bash |
| 61 | +porchctl rpkg get --namespace default |
| 62 | +``` |
| 63 | + |
| 64 | +You should see your package revision listed with lifecycle `Draft`: |
| 65 | + |
| 66 | +```bash |
| 67 | +NAME PACKAGE WORKSPACENAME REVISION LATEST LIFECYCLE REPOSITORY |
| 68 | +porch-test.my-first-package.v1 my-first-package v1 0 false Draft porch-test |
| 69 | +``` |
| 70 | + |
| 71 | +--- |
| 72 | + |
| 73 | +## Step 2: Pull the Package Revision Locally |
| 74 | + |
| 75 | +Download the package revision contents to your local filesystem: |
| 76 | + |
| 77 | +```bash |
| 78 | +porchctl rpkg pull porch-test.my-first-package.v1 ./my-first-package --namespace default |
| 79 | +``` |
| 80 | + |
| 81 | +**What this does:** |
| 82 | + |
| 83 | +- Fetches all resources from the PackageRevision |
| 84 | +- Saves them to the `./my-first-package` directory |
| 85 | +- Includes the Kptfile and any other resources |
| 86 | + |
| 87 | + |
| 88 | + |
| 89 | +**Explore the package revision contents:** |
| 90 | + |
| 91 | +```bash |
| 92 | +ls -al ./my-first-package |
| 93 | +``` |
| 94 | + |
| 95 | +You'll see: |
| 96 | + |
| 97 | +- The `Kptfile` - PackageRevision metadata and pipeline configuration |
| 98 | +- Other YAML files (if any were created) |
| 99 | + |
| 100 | +```bash |
| 101 | +total 24 |
| 102 | +drwxr-x--- 2 user user 4096 Nov 24 13:27 . |
| 103 | +drwxr-xr-x 4 user user 4096 Nov 24 13:27 .. |
| 104 | +-rw-r--r-- 1 user user 259 Nov 24 13:27 .KptRevisionMetadata |
| 105 | +-rw-r--r-- 1 user user 177 Nov 24 13:27 Kptfile |
| 106 | +-rw-r--r-- 1 user user 488 Nov 24 13:27 README.md |
| 107 | +-rw-r--r-- 1 user user 148 Nov 24 13:27 package-context.yaml |
| 108 | +``` |
| 109 | + |
| 110 | +**Alternatively:** |
| 111 | + |
| 112 | +If you have the tree command installed on your system you can use it to view the hierarchy of the package |
| 113 | + |
| 114 | +```bash |
| 115 | +tree ./my-first-package/ |
| 116 | +``` |
| 117 | + |
| 118 | +Should return the following output: |
| 119 | + |
| 120 | +```bash |
| 121 | +my-first-package/ |
| 122 | +├── Kptfile |
| 123 | +├── README.md |
| 124 | +└── package-context.yaml |
| 125 | + |
| 126 | +1 directory, 3 files |
| 127 | +``` |
| 128 | + |
| 129 | +--- |
| 130 | + |
| 131 | +## Step 3: Modify the Package Revision |
| 132 | + |
| 133 | +Let's add a simple KRM function to the pipeline. |
| 134 | + |
| 135 | +Open the `Kptfile` in your editor of choice: |
| 136 | + |
| 137 | +```bash |
| 138 | +vim ./my-first-package/Kptfile |
| 139 | +``` |
| 140 | + |
| 141 | +Add a mutator function to the pipeline section so that your `Kptfile` looks like so: |
| 142 | + |
| 143 | +```yaml |
| 144 | +apiVersion: kpt.dev/v1 |
| 145 | +kind: Kptfile |
| 146 | +metadata: |
| 147 | + name: my-first-package |
| 148 | + annotations: |
| 149 | + config.kubernetes.io/local-config: "true" |
| 150 | +info: |
| 151 | + description: My first Porch package |
| 152 | +pipeline: |
| 153 | + mutators: |
| 154 | + - image: gcr.io/kpt-fn/set-namespace:v0.4.1 |
| 155 | + configMap: |
| 156 | + namespace: production |
| 157 | +``` |
| 158 | +
|
| 159 | +**What this does:** |
| 160 | +
|
| 161 | +- Adds a `set-namespace` function to the pipeline |
| 162 | +- This function will set the namespace to `production` for all resources |
| 163 | +- These Functions are not rendered until the package is "pushed" to porch |
| 164 | + |
| 165 | +**Add new resource:** |
| 166 | + |
| 167 | +Create a new configmap: |
| 168 | + |
| 169 | +```bash |
| 170 | +vim ./my-first-package/test-config.yaml |
| 171 | +``` |
| 172 | + |
| 173 | +Now add the following content to this new configmap |
| 174 | + |
| 175 | +```yaml |
| 176 | +apiVersion: v1 |
| 177 | +kind: ConfigMap |
| 178 | +metadata: |
| 179 | + name: test-config |
| 180 | +data: |
| 181 | + key: "value" |
| 182 | +``` |
| 183 | + |
| 184 | +**Save and close the file.** |
| 185 | + |
| 186 | +{{% alert title="Note" color="primary" %}} |
| 187 | +Changes are LOCAL ONLY (Porch doesn't know about them yet) at this stage |
| 188 | +{{% /alert %}} |
| 189 | + |
| 190 | +--- |
| 191 | + |
| 192 | +## Step 4: Push Changes Back to Porch |
| 193 | + |
| 194 | +Upload your modified package revision back to Porch: |
| 195 | + |
| 196 | +```bash |
| 197 | +porchctl rpkg push porch-test.my-first-package.v1 ./my-first-package --namespace default |
| 198 | +``` |
| 199 | + |
| 200 | +**What this does:** |
| 201 | + |
| 202 | +- Updates the PackageRevision in Porch |
| 203 | +- Triggers rendering (executes pipeline functions) |
| 204 | +- PackageRevision remains in `Draft` state |
| 205 | + |
| 206 | + |
| 207 | + |
| 208 | +**Successful output:** |
| 209 | + |
| 210 | +This describes how the KRM function was run by porch and has updated the namespace in our new configmap. |
| 211 | + |
| 212 | +```bash |
| 213 | +[RUNNING] "gcr.io/kpt-fn/set-namespace:v0.4.1" |
| 214 | +[PASS] "gcr.io/kpt-fn/set-namespace:v0.4.1" |
| 215 | + Results: |
| 216 | + [info]: namespace "" updated to "production", 1 value(s) changed |
| 217 | +porch-test.my-first-package.v1 pushed |
| 218 | +``` |
| 219 | + |
| 220 | +--- |
| 221 | + |
| 222 | +## Step 5: Propose the Package Revision |
| 223 | + |
| 224 | +Move the package revision to `Proposed` state for review: |
| 225 | + |
| 226 | +```bash |
| 227 | +porchctl rpkg propose porch-test.my-first-package.v1 --namespace default |
| 228 | +``` |
| 229 | + |
| 230 | +**What this does:** |
| 231 | + |
| 232 | +- Changes lifecycle from `Draft` to `Proposed` |
| 233 | +- Signals the package revision is ready for review |
| 234 | +- PackageRevision can still be modified if needed |
| 235 | + |
| 236 | + |
| 237 | + |
| 238 | +{{% alert title="Note" color="primary" %}} |
| 239 | +A lifecycle state change from `Draft` to `Proposed` means that in Git the package revision has moved from the `draft` branch to the `proposed` branch |
| 240 | +{{% /alert %}} |
| 241 | + |
| 242 | +**Verify the state change:** |
| 243 | + |
| 244 | +```bash |
| 245 | +porchctl rpkg get porch-test.my-first-package.v1 --namespace default |
| 246 | +``` |
| 247 | + |
| 248 | +The lifecycle should now show `Proposed`. |
| 249 | + |
| 250 | +```bash |
| 251 | +NAME PACKAGE WORKSPACENAME REVISION LATEST LIFECYCLE REPOSITORY |
| 252 | +porch-test.my-first-package.v1 my-first-package v1 0 false Proposed porch-test |
| 253 | +``` |
| 254 | + |
| 255 | +--- |
| 256 | + |
| 257 | +## Step 6a: Approve the Package Revision |
| 258 | + |
| 259 | +If the package revision looks good, approve it to publish: |
| 260 | + |
| 261 | +```bash |
| 262 | +porchctl rpkg approve porch-test.my-first-package.v1 --namespace default |
| 263 | +``` |
| 264 | + |
| 265 | +**What this does:** |
| 266 | + |
| 267 | +- Changes PackageRevision lifecycle from `Proposed` (revision 0) to `Published` (revision 1) |
| 268 | +- PackageRevision becomes **immutable** (content cannot be changed) |
| 269 | +- Records who approved and when |
| 270 | +- PackageRevision is now available for cloning/deployment |
| 271 | + |
| 272 | + |
| 273 | + |
| 274 | +**Verify publication:** |
| 275 | + |
| 276 | +```bash |
| 277 | +porchctl rpkg get porch-test.my-first-package.v1 --namespace default -o yaml | grep -E "lifecycle|publishedBy|publishTimestamp" |
| 278 | +``` |
| 279 | + |
| 280 | +**Verify the state change:** |
| 281 | + |
| 282 | +```bash |
| 283 | +porchctl rpkg get porch-test.my-first-package.v1 --namespace default |
| 284 | +``` |
| 285 | + |
| 286 | +The lifecycle should now show `Published`. |
| 287 | + |
| 288 | +```bash |
| 289 | +NAME PACKAGE WORKSPACENAME REVISION LATEST LIFECYCLE REPOSITORY |
| 290 | +porch-test.my-first-package.v1 my-first-package v1 1 true Published porch-test |
| 291 | +``` |
| 292 | + |
| 293 | +--- |
| 294 | + |
| 295 | +## Step 6b: Reject the Package Revision (Alternative) |
| 296 | + |
| 297 | +If the package revision needs more work, reject it to return to `Draft`: |
| 298 | + |
| 299 | +```bash |
| 300 | +porchctl rpkg reject porch-test.my-first-package.v1 --namespace default |
| 301 | +``` |
| 302 | + |
| 303 | +**What this does:** |
| 304 | + |
| 305 | +- Changes lifecycle from `Proposed` back to `Draft` |
| 306 | +- Allows further modifications |
| 307 | +- You can then make changes and re-propose |
| 308 | + |
| 309 | + |
| 310 | + |
| 311 | +If the package revision is rejected, the process begins again from Step 2 until the desired state is achieved. |
| 312 | + |
| 313 | + |
| 314 | + |
| 315 | +--- |
| 316 | + |
| 317 | +## Troubleshooting |
| 318 | + |
| 319 | +**PackageRevision stuck in Draft?** |
| 320 | + |
| 321 | +- Check readiness conditions: `porchctl rpkg get <PACKAGE-REVISION> -o yaml | grep -A 5 conditions` |
| 322 | + |
| 323 | +**Push fails with conflict?** |
| 324 | + |
| 325 | +- Pull the latest version first: `porchctl rpkg pull <PACKAGE-REVISION> ./dir` |
| 326 | +- The PackageRevision may have been modified by someone else |
| 327 | + |
| 328 | +**Cannot modify Published PackageRevision?** |
| 329 | + |
| 330 | +- Published PackageRevisions are immutable |
| 331 | +- Create a new revision using `porchctl rpkg copy` [Copying Package Revisions Guide]({{% relref "/docs/neo-porch/4_tutorials_and_how-tos/copying-packages.md" %}}). |
| 332 | + |
| 333 | +--- |
| 334 | + |
| 335 | +## Understanding PackageRevision Names |
| 336 | + |
| 337 | +Porch generates PackageRevision names automatically: |
| 338 | + |
| 339 | +- Format: `{repoName}.{packageName}.{workspaceName}` |
| 340 | +- Example: `porch-test.my-first-package.v1` |
| 341 | +- The workspace name must be unique within the package |
| 342 | +- Multiple PackageRevisions can share the same package name but have different workspaces |
| 343 | + |
| 344 | +--- |
| 345 | + |
| 346 | +## Key Concepts |
| 347 | + |
| 348 | +- **PackageRevision**: The Kubernetes resource managed by Porch (there is no separate "Package" resource) |
| 349 | +- **Draft**: Work in progress, fully editable |
| 350 | +- **Proposed**: Ready for review, still editable |
| 351 | +- **Published**: Approved and immutable |
| 352 | +- **Workspace**: Unique identifier for a PackageRevision within a package |
| 353 | +- **Repository**: Git repo where PackageRevisions are stored |
| 354 | +- **Pipeline**: KRM functions that transform PackageRevision resources |
| 355 | +- **Revision Number**: 0 for Draft/Proposed, 1+ for Published (increments with each publication) |
| 356 | + |
| 357 | +--- |
0 commit comments