Skip to content

Commit bd89450

Browse files
feat(postman): add cleanup process for sunsetted collections
1 parent 72a32a4 commit bd89450

3 files changed

Lines changed: 123 additions & 0 deletions

File tree

.github/workflows/release-postman.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,11 @@ jobs:
5757
working-directory: ./tools/postman
5858
run: |
5959
make upload_collection
60+
61+
- name: Delete Sunsetted Collections
62+
env:
63+
POSTMAN_API_KEY: ${{ secrets.postman_api_key }}
64+
WORKSPACE_ID: ${{ secrets.workspace_id }}
65+
working-directory: ./tools/postman
66+
run: |
67+
make delete_sunsetted

tools/postman/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ transform_collection_test:
2929
upload_collection:
3030
./scripts/upload-collection.sh
3131

32+
.PHONY: delete_sunsetted
33+
delete_sunsetted:
34+
./scripts/delete-sunsetted-collections.sh
35+
3236
.PHONY: build
3337
build: fetch_openapi convert_to_collection
3438

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
#########################################################
5+
# Delete Postman collections for sunsetted API versions.
6+
# A collection is deleted when BOTH conditions are true:
7+
# 1. Its version date is NOT in versions.json
8+
# 2. Its version date is before today
9+
#
10+
# Environment variables:
11+
# POSTMAN_API_KEY - API Key for Postman API
12+
# WORKSPACE_ID - Identifier for the Postman Workspace
13+
# FULL_OPENAPI_FOLDER - Path to openapi/v2/ directory (default: ../../openapi/v2/)
14+
# TMP_FOLDER - Folder for temporary files (default: ../tmp)
15+
#########################################################
16+
17+
FULL_OPENAPI_FOLDER=${FULL_OPENAPI_FOLDER:-"../../openapi/v2/"}
18+
TMP_FOLDER=${TMP_FOLDER:-"../tmp"}
19+
COLLECTIONS_LIST_FILE="${TMP_FOLDER}/collections-list-cleanup.json"
20+
VERSIONS_JSON="${FULL_OPENAPI_FOLDER}versions.json"
21+
22+
execute_curl() {
23+
local args=("$@")
24+
if [[ "${RUNNER_DEBUG:-0}" == "1" ]]; then
25+
args+=("-v")
26+
echo "Debug mode enabled - using verbose curl output"
27+
fi
28+
curl "${args[@]}" 2>&1 | grep -i -v "api-key\|x-api-key\|PMAK-" || true
29+
}
30+
31+
if [[ ! -f "${VERSIONS_JSON}" ]]; then
32+
echo "ERROR: versions.json not found at ${VERSIONS_JSON}"
33+
exit 1
34+
fi
35+
36+
today=$(date -u +%Y-%m-%d)
37+
38+
echo "Fetching list of collections from workspace"
39+
echo "curl -o ${COLLECTIONS_LIST_FILE} --location 'https://api.getpostman.com/collections?workspace=${WORKSPACE_ID}' --header 'X-API-Key: **********'"
40+
execute_curl --show-error --fail --silent \
41+
--retry 3 --retry-delay 30 --retry-max-time 1200 --retry-all-errors \
42+
-o "${COLLECTIONS_LIST_FILE}" \
43+
--location "https://api.getpostman.com/collections?workspace=${WORKSPACE_ID}" \
44+
--header "X-API-Key: ${POSTMAN_API_KEY}"
45+
46+
if ! jq -e '.collections' "${COLLECTIONS_LIST_FILE}" > /dev/null 2>&1; then
47+
echo "ERROR: Failed to fetch collections list - response missing 'collections' key"
48+
exit 1
49+
fi
50+
51+
collection_count=$(jq '.collections | length' "${COLLECTIONS_LIST_FILE}")
52+
if [[ "${collection_count}" -eq 0 ]]; then
53+
echo "[INFO] No collections found in workspace"
54+
exit 0
55+
fi
56+
57+
echo "Current collections in the workspace:"
58+
jq '.collections[] | {id, name}' "${COLLECTIONS_LIST_FILE}"
59+
60+
deleted=0
61+
62+
while IFS= read -r row; do
63+
id=$(echo "${row}" | jq -r '.id')
64+
name=$(echo "${row}" | jq -r '.name')
65+
66+
# Never delete the starred (current) collection
67+
if [[ "${name}" == *""* ]]; then
68+
echo "[SKIP] Keeping starred (current) collection: ${name}"
69+
continue
70+
fi
71+
72+
# Extract version date (YYYY-MM-DD) from the collection name
73+
version=$(echo "${name}" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -1 || true)
74+
if [[ -z "${version}" ]]; then
75+
echo "[SKIP] Keeping collection with no version date in name: ${name}"
76+
continue
77+
fi
78+
79+
# Condition 1: version must NOT be in versions.json
80+
in_versions=$(jq --arg v "${version}" 'map(select(. == $v)) | length' "${VERSIONS_JSON}")
81+
if [[ "${in_versions}" -gt 0 ]]; then
82+
echo "[SKIP] Keeping collection for active version ${version}: ${name}"
83+
continue
84+
fi
85+
86+
# Condition 2: version date must be before today
87+
if [[ "${version}" > "${today}" || "${version}" == "${today}" ]]; then
88+
echo "[SKIP] Keeping collection for future or today version ${version}: ${name}"
89+
continue
90+
fi
91+
92+
# Both conditions met — delete
93+
echo "[DELETE] Removing collection: ${name} (id: ${id})"
94+
echo "curl --request DELETE --location 'https://api.getpostman.com/collections/${id}' --header 'X-API-Key: **********'"
95+
96+
http_code=$(execute_curl --silent --show-error \
97+
--write-out "%{http_code}" \
98+
-o /dev/null \
99+
--request DELETE \
100+
--location "https://api.getpostman.com/collections/${id}" \
101+
--header "X-API-Key: ${POSTMAN_API_KEY}")
102+
103+
if [[ "${http_code}" != "200" ]]; then
104+
echo "[ERROR] Failed to delete collection: ${name} (id: ${id}), HTTP status: ${http_code}"
105+
else
106+
deleted=$((deleted + 1))
107+
fi
108+
109+
done < <(jq -c '.collections[]' "${COLLECTIONS_LIST_FILE}")
110+
111+
echo "[SUMMARY] Deleted ${deleted} sunsetted collection(s)"

0 commit comments

Comments
 (0)