Files
Lin Manhui 6a8b8f1e32 [Feat] Add PP-OCRv6 iOS Demo (#17933)
* Update for paddleocr 3.5

* Fix doc

* Add doc to nav

* Refine docs

* Fix PaddleOCR-VL doc

* Polish PaddleOCR-VL docs

* Polish docs

* Add notice

* Polish doc

* docs: initialize project

* Init

* feat(02-02): port Clipper polygon offset algorithm to pure Swift

- Implement ClipperOffset class with addPath/execute API
- Support JT_ROUND + ET_CLOSEDPOLYGON for DB postprocessing
- Add static offsetPolygon() convenience for DBPostProcess
- Arc tolerance calculation matches pyclipper's Clipper 6.x
- Pure Swift, no external dependencies

* feat(02-01): add Yams dependency and InferenceConfig YAML parser

- Add Yams ~> 5.0 pod to Podfile for inference.yml parsing
- Create InferenceConfig.swift with typed parsing of inference.yml
- Support TransformOp enum: DetResizeForTest, NormalizeImage, ToCHWImage, RecResizeImg
- PostProcessConfig handles both det (DBPostProcess) and rec (CTCLabelDecode) configs
- Python-style scale string '1./255.' parsed via string splitting (not eval)
- Register InferenceConfig.swift in Xcode project

* feat(02-01): implement pure-Swift detection preprocessing operators

- Create Preprocessing.swift with DetPreprocessor and PreprocessResult
- Port DetResizeForTest: resize longest side to resize_long, ceil to 128 stride
- Port NormalizeImage: config-driven scale/mean/std normalization
- Port ToCHWImage: HWC-to-CHW layout conversion producing [1,3,H,W] tensor
- Image padding for tiny images (h+w < 64) matching Python reference
- Pure Swift using CoreGraphics + Accelerate (no OpenCV dependency)
- All transform parameters read from InferenceConfig (zero hardcoded values)
- Register Preprocessing.swift in Xcode project

* feat(02-02): implement DB text detection postprocessing pipeline

- Add DBPostProcessor with full pipeline: threshold -> contours -> minAreaRect -> score -> expand -> scale
- Implement Suzuki-Abe contour finding with CHAIN_APPROX_SIMPLE compression
- Implement rotating calipers minAreaRect + convex hull (Andrew's monotone chain)
- Add scanline polygon fill for box_score_fast computation
- Integrate ClipperOffset for polygon expansion (unclip)
- All parameters configurable via DBPostProcessConfigurable protocol
- Pure Swift, no OpenCV dependency

* docs(02-02): create SUMMARY.md for ClipperOffset + DBPostProcess plan

* feat(02-03): expose runDetection method on ORTSessionManager

- Add runDetection(inputData:shape:) for real inference with preprocessed data
- Returns output tensors as [String: (data: [Float], shape: [Int])] dictionary
- Includes NaN validation on output tensors
- All existing methods (loadModels, validateDetModel, validateRecModel) preserved unchanged

* feat(02-03): create DetectionEngine orchestrating full detection pipeline

- DetectionEngine wires DetPreprocessor -> ORTSessionManager.runDetection -> DBPostProcessor
- DetectionResult struct with boxes and per-stage timing metrics (preprocess/inference/postprocess)
- All parameters loaded from inference.yml via InferenceConfig.load()
- PostProcessConfig conforms to DBPostProcessConfigurable for type-safe init bridging
- DetectionEngineError for noOutputTensor and unexpectedOutputShape cases
- Registered in Xcode project pbxproj

* docs(02-03): complete detection engine integration plan

- SUMMARY.md documenting DetectionEngine pipeline integration
- STATE.md updated with position, decisions, metrics
- REQUIREMENTS.md: POST-01, POST-02 marked complete

* docs(phase-02): verification complete — human_needed for runtime numerical exactness

* docs(phase-02): complete phase execution

* docs(phase-02): evolve PROJECT.md after phase completion

* feat(03-01): add runRecognition to ORTSessionManager with shared inference method

- Extract private runInference() from runDetection to eliminate code duplication
- Add public runRecognition() method that uses recSession for recognition model inference
- Both runDetection and runRecognition guard their respective sessions and delegate to runInference
- Recognition model supports dynamic-width input tensors [1, 3, 48, W]

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(03-01): create RecPreprocessor implementing OCRResizeNormImg

- Implement OCRResizeNormImg algorithm matching PaddleX text_recognition/processors.py
- Read imgC/imgH/imgW from inference.yml RecResizeImg.image_shape (config-driven, not hardcoded)
- Aspect-ratio-aware resize with ceil() width computation matching Python math.ceil()
- Recognition normalization: pixel/127.5 - 1.0 mapping [0,255] to [-1,1] (not ImageNet mean/std)
- HWC-to-CHW transpose and right-pad with zeros to target width
- Bilinear interpolation via CGContext (pure Swift, no OpenCV)
- Register RecPreprocessor.swift in Xcode project (PBXBuildFile, PBXFileReference, PBXGroup, Sources)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(03-01): complete recognition preprocessing & inference plan

- Create 03-01-SUMMARY.md documenting plan execution
- Update STATE.md: advance to Phase 3 Plan 1 complete, add decisions
- Update ROADMAP.md: Phase 3 progress 1/2
- Update REQUIREMENTS.md: mark PREP-04 and PREP-05 as complete

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(03-02): create CTCDecoder implementing CTC label decode with character dictionary

- CTCDecoder struct ported from ppocr/postprocess/rec_postprocess.py CTCLabelDecode
- Reads character_dict from inference.yml PostProcess config
- Prepends blank token at index 0 (CTC convention)
- Decoding: argmax + consecutive duplicate removal + blank filtering + char mapping
- Confidence: mean probability of selected timesteps
- Registered in Xcode project (Engine group)

* feat(03-02): create RecognitionEngine orchestrating full recognition pipeline

- RecognitionEngine class mirrors DetectionEngine pattern
- Composes RecPreprocessor + ORTSessionManager.runRecognition + CTCDecoder
- Returns RecognitionEngineResult with text, confidence, and per-stage timing
- Config-driven: reads inference.yml for preprocessing dims and character dictionary
- Registered in Xcode project (Engine group)

* docs(03-02): complete CTC decoding and recognition engine integration plan

- 03-02-SUMMARY.md with frontmatter, accomplishments, and self-check
- STATE.md updated with position, decisions, metrics
- ROADMAP.md Phase 3 marked 2/2 complete
- REQUIREMENTS.md POST-03, POST-04 marked complete

* docs(03): create gap closure plan for CTCDecoder missing space character

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(03-03): append ASCII space to CTCDecoder dictionary for 18,385-element parity

- Add chars.append(" ") after dict chars to match PaddleX use_space_char=True default
- Update doc comments to document full 18,385-element character list layout
- Fixes model output class index 18384 being silently dropped during decode

* docs(03-03): complete CTC decoder space character fix plan

- Created 03-03-SUMMARY.md with execution results
- Updated STATE.md with plan completion and metrics
- Updated ROADMAP.md with plan 03-03 completion status

* merge: integrate phase 03-03 gap closure from worktree

* docs(phase-03): complete phase execution — 7/7 must-haves verified

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(phase-03): evolve PROJECT.md after phase completion

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(04): create phase plan for Pipeline Orchestration & Validation

3 plans in 2 waves:
- Plan 01 (Wave 1): BoxSorter + PerspectiveCrop algorithms
- Plan 02 (Wave 1): Python validation scripts (generate_reference.py + validate.py)
- Plan 03 (Wave 2): OCREngine orchestrator + ValidationExport JSON serializer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(04-02): add PaddleX reference output generator for iOS validation

- generate_reference.py runs PaddleOCR on test images, exports per-image
  JSON with polygon coordinates, text, and confidence scores
- Creates test_images/ directory with .gitkeep for developer-provided images
- .gitignore excludes generated reference/ directory from version control
- Supports PP-OCRv5 mobile det/rec models with all optional processors disabled

* feat(04-01): implement BoxSorter reading-order sort

- Port PaddleX SortQuadBoxes algorithm to Swift
- Two-phase sort: initial y/x sort + backward insertion for same-line reorder
- yThreshold=10 matching PaddleX hardcoded value
- Consumes DetectionBox type from DBPostProcess.swift

* feat(04-02): add iOS vs reference validation script and README

- validate.py compares iOS JSON output against PaddleX reference JSON
  with exact polygon/text match and 1e-4 confidence tolerance
- Prints per-image PASS/FAIL and overall summary with box match counts
- Exit codes: 0=pass, 1=fail, 2=missing files (CI-friendly)
- README.md documents complete validation workflow (generate -> export -> validate)

* feat(04-01): implement PerspectiveCrop with DLT warp and tall-narrow rotation

- Port PaddleX get_rotate_crop_image algorithm to pure Swift
- DLT perspective matrix solve via 8x8 Gaussian elimination
- Backward-mapping bilinear warp with BORDER_REPLICATE clamping
- 90-degree CCW rotation when height/width >= 1.5
- Float64 precision for matrix computation, Float for pixel sampling
- CoreGraphics-only: no OpenCV dependency

* docs(04-02): complete validation scripts plan

- SUMMARY.md documenting plan execution (2 tasks, 5 files, 4min)
- STATE.md updated with position, decisions, metrics
- ROADMAP.md updated with Phase 04 progress (1/3 plans)
- REQUIREMENTS.md marks VALID-01, VALID-02, PIPE-05 complete

* docs(04-01): complete pipeline bridge algorithms plan

- SUMMARY.md with BoxSorter and PerspectiveCrop execution results
- STATE.md updated with Phase 04 position and decisions
- ROADMAP.md updated with plan progress (1/3)
- REQUIREMENTS.md marked PIPE-02, PIPE-03 complete

* feat(04-03): add OCREngine pipeline orchestrator with per-stage timing

- Composes DetectionEngine, BoxSorter, PerspectiveCrop, RecognitionEngine
- Async run() method: detect -> sort -> crop -> recognize flow
- OCRResult and OCRPipelineResult types with per-stage timing breakdown
- Zero hardcoded params; all config-driven via inference.yml

* feat(04-03): add ValidationExport JSON serializer for pipeline output

- Serializes OCRPipelineResult to JSON matching Python validation schema
- Schema: {image, box_count, boxes: [{polygon, text, confidence}]}
- writeJSON writes to Documents/validation_output/ for device extraction
- Sorted keys for deterministic output diffs

* docs(04-03): complete pipeline orchestration plan

- OCREngine + ValidationExport implemented and committed
- STATE.md, ROADMAP.md, REQUIREMENTS.md updated
- PIPE-01, PIPE-04, CONF-02, CONF-03, CONF-04, CONF-05 marked complete

* docs(phase-04): complete phase execution — 10/10 must-haves verified

* docs(phase-04): evolve PROJECT.md after phase completion

* docs(05-user-interface): create phase plan

Two plans for Phase 5 UI: Plan 01 (wave 1) establishes OCRViewModel
state machine, PhotosPicker integration, sample images, and ContentView
coordinator. Plan 02 (wave 2) adds ResultImageView with Canvas polygon
overlay, TimingView, ResultsListView with clipboard copy, ErrorView,
and a human verification checkpoint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(05-01): create OCRViewModel with full lifecycle state machine

- Add AppState enum with 5 states: loadingModels, ready, processing, results, error
- Add AppError enum with modelLoadFailed, inferenceFailed, imageLoadFailed cases
- Add OCRViewModel @MainActor class managing full app lifecycle via single @Published state
- Implement loadModels, processImage, selectSampleImage, copyResultsToClipboard, retry, reset
- Add normalizeOrientation helper for EXIF rotation flattening
- Fix missing pbxproj entries for OCREngine, BoxSorter, PerspectiveCrop, ValidationExport (Rule 3)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(05-01): create ImagePickerSection and bundle sample images

- Add ImagePickerSection.swift with PhotosPicker + sample thumbnail row
- Bundle 3 sample images: English (book.jpg), Chinese (PP-OCRv3-pic001), multiline (table.jpg)
- Add SampleImages as folder reference in Xcode project Resources build phase
- Add Views group and Resources group to Xcode project structure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(05-01): rewrite ContentView as state coordinator, retire AppViewModel

- Rewrite ContentView to use OCRViewModel with state-driven rendering
- Add NavigationStack with inline title "PaddleOCR Demo"
- Implement 5 state views: loadingModels, ready, processing, results, error
- Wire PhotosPicker via onChange binding with Data loadTransferable
- Integrate ImagePickerSection in ready, results, and non-model-error states
- Show processing overlay spinner on selected image
- Add placeholder results view with text list and timing (Plan 02 replaces)
- Error view with context-specific heading and Retry button
- Replace AppViewModel.swift contents with empty stub comment

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(05-01): complete view model + image selection plan

- Create 05-01-SUMMARY.md with execution results and self-check
- Update STATE.md: Phase 5 Plan 1 complete, add decisions
- Update ROADMAP.md: Phase 5 progress (1/2 plans)
- Mark requirements UI-01, UI-02, UI-07, UI-08 as complete

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* merge: resolve STATE.md conflict after 05-01 execution

* feat(05-02): add ResultImageView with Canvas polygon overlay and TimingView

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(05-02): add ResultsListView, ErrorView, and wire all views into ContentView

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* update docs

* update

* update

* Fix and update

* update speed data

* Optimize UI

* add warning

* update warning

* update warning

* update warning

* update warning

* update

* update

* Remove cached inference.yml files

* Fix bugs

* Update API docs

* Update API docs

* Fix

* Update

* Update git ignore

* Update docs

* Refactor and align with Python

* Fix config settting

* Optimize code

* Allow engine selection

* Restructure folders

* Support batch inference

* update pp_structure_v3 case

* update

* Init validation toolkit

* Hack paddleocr

* Allow specifying URLs for pdx and ppocr version

* docs: release-review fixes for 3.5 docs

Addresses issues surfaced during release-time review of #17820,
covering broken rendering, broken cross-language and anchor links,
expression and consistency nits, and the strict-mode docs-anchor CI.

Rendering fixes:
- Restore truncated/duplicated parameter-table rows in OCR.en.md,
  PP-DocTranslation.en.md, PP-StructureV3.en.md, and
  doc_understanding.en.md
- Fix mis-indented kwarg in the PP-DocTranslation.en.md transformers
  example (would SyntaxError on copy-paste)
- Fix 4-backtick closing fence and over-wide rowspan in
  chart_parsing.{en,zh}.md
- Fill in empty enable_hpi default (None) in PaddleOCR-VL.en.md

Link fixes:
- Point module_usage .en.md files at ../inference_engine.en.md
  instead of the Chinese ../inference_engine.md (11 files)
- Replace Chinese anchor #五推理引擎 with #5-inference-engine in
  eight module_usage .en.md files, and normalize the corresponding
  heading from "## V. Inference Engine" to "## 5. Inference Engine"
  in textline_orientation_classification.en.md
- Correct mislabeled PaddleX weight-conversion link text in
  text_detection.en.md and table_structure_recognition.en.md
- Align broken cross-file link in inference_engine.md with the
  actual slug (#3-paddlex) so it stops conflicting with
  high_performance_inference.md and serving.md

Chinese anchor resolution (CI fix):
- Attach explicit {#anchor} (attr_list) attributes to the zh
  headings for "推理引擎", "权重转换", and "流程导览" so the
  existing in-page Chinese anchors resolve under the default
  mkdocs slugify. Build now clean under `mkdocs-ci.yml` strict mode.

Expression and consistency:
- Drop duplicated "and vLLM" phrase in NVIDIA Blackwell WARNING
- Restore Chinese key "驾驶室准乘人数" in PP-ChatOCRv4.en.md
  transformers example (rest of the doc keeps it)
- Normalize "Paddle framework" to "PaddlePaddle framework" and
  align link text with target file title across affected docs
- Fix plural/singular mismatch ("examples"/"them" -> "example"/"it")
  in module_usage .en.md quick-start intros that show one command
- Add missing comma after hardware names in five hardware EN tutorials
- Add spacing in "PaddleX 产线 Python 脚本使用说明" link text in
  inference_engine.md
- Use uppercase CPU/GPU in paddlepaddle_installation.md comments

Navigation:
- Add missing English nav_translations entries so the English
  sidebar no longer shows raw Chinese labels:
    PP-DocTranslation产线 -> PP-DocTranslation Pipeline
    推理引擎与配置说明     -> Inference Engine and Configuration

Signed-off-by: Bvicii <yizhanhuang2002@gmail.com>

* docs: clarify that engine=None preserves legacy PaddleOCR behavior

Addresses PR #17820 review feedback: the engine-parameter row lists
`paddle`, `paddle_static`, `paddle_dynamic`, and `transformers` as
supported values but doesn't mention that `None` is also valid (and
is the default). Add a short user-facing clarification to every engine
row's Description so readers who see `default=None` understand what
that means:

- EN: "If left as `None` (the default), PaddleOCR preserves the
  behavior of earlier versions, which in most configurations is
  equivalent to `paddle`."
- ZH: "保持为默认值 None 时,PaddleOCR 保留旧版本的行为,在大多数配置下
  等价于 paddle。"

48 files, 66 engine rows updated (33 EN + 33 ZH). No changes to
engine_config rows, which use a different description.

Signed-off-by: Bvicii <yizhanhuang2002@gmail.com>

* Remove planning files

* Fix code style

* Optimize docs

* Update docs

* docs: align CUDA 12.6 Docker driver version with pip section

Per review feedback from changdazhou on PR #17820 (L26), update the
CUDA 12.6 Docker GPU line to require driver >= 550.54.14, matching
the pip section already at L61 (both ZH and EN).

Signed-off-by: Bvicii <yizhanhuang2002@gmail.com>

* docs: include None in engine supported-values list

Per follow-up review on PR #17820: from a completeness standpoint,
None belongs in the "Supports ..." enumeration rather than only in
the trailing clarification sentence. Move None into the list as the
default value and tighten the follow-on sentence accordingly.

- EN: "Supports None (the default), paddle, paddle_static,
  paddle_dynamic, and transformers. When left as None, PaddleOCR
  preserves the behavior of earlier versions..."
- ZH: "支持 None(默认值)、paddle、paddle_static、paddle_dynamic、
  transformers。保持为默认值 None 时..."

Applied to all three supported-value variants across the module_usage
and pipeline_usage pages — same 48 files / 66 rows as the previous
clarification commit.

Signed-off-by: Bvicii <yizhanhuang2002@gmail.com>

* Fix benchmark

* Add icon and fix validation

* ci,docs: align PaddleX install branch and document py3.8 extras boundary (#17954) (#17961)

* ci,docs: align PaddleX install branch and document py3.8 extras boundary

- CI: derive the PaddleX install branch from the paddlex constraint in
  pyproject.toml (release/X.Y) so PR/GPU tests stay in sync as the
  paddleocr series advances; apply to both tests.yml and test_gpu.yml
- CI: install only paddleocr[doc2md] on py3.8 since several paddlex
  transitive deps require py3.9+; add a py38_incompatible pytest marker
  and gate affected tests behind it
- CI: pin paddlepaddle==3.0.0 on py3.8 / 3.1.0 on py3.9+ (match GPU CI)
- CI: standardize workflow filenames (.yaml -> .yml, dashes -> underscores)
- deps: pin lmdb<1.5 on py3.8 (newer lmdb wheels reference Py_SET_REFCNT,
  a py3.9 stdlib C API)
- docs: note Python 3.8+ for base paddleocr/doc2md; py3.9+ for
  doc-parser/ie/trans/all extras (safetensors>=0.7 dropped py3.8)
- docs: update PaddleOCR-VL manual-install Python range to 3.9-3.13
  across all hardware variants (VL pipelines use doc-parser)
- tests: tag tests that require py3.9+ extras/deps with py38_incompatible



* ci: mark /workspace as git safe.directory in GPU runner

setuptools_scm runs git to derive the package version during
pip install -e .; inside the GPU CI container /workspace is owned
by the host user, which trips git's dubious-ownership check and
aborts the paddleocr install.



---------


(cherry picked from commit 09e8700fe6)

Signed-off-by: Bvicii <yizhanhuang2002@gmail.com>

* Add quantization

* docs(ios_demo): add build_onnx_calib_npy.py and README for static calib .npy

Made-with: Cursor

* Enhance quantization and support ort format

* Fix skills

* Fix installation docs

* Enhance benchmark

* Use release config

* By default use CPU

* Support setting session options

* Enhance UI

* Update benchmark docs

* Fix wrong updates

* reset skill updates

* Update .gitignore

* Add chinese docs

* Support PP-OCRv5_mobile

* Remove on-device deployment

* Fix anchor:

---------

Signed-off-by: Bvicii <yizhanhuang2002@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: zhangyue66 <zhangyue66@baidu.com>
Co-authored-by: Bvicii <yizhanhuang2002@gmail.com>
Co-authored-by: Bvicii <98971614+scyyh11@users.noreply.github.com>
2026-06-11 12:48:03 +08:00

5.9 KiB

PaddleOCR Release SOP

中文

Scope

This document describes the standard release process for PaddleOCR.

Release Types

The current process supports the following two release types:

  • bump patch: for example, 3.4.0 -> 3.4.1
  • bump minor: for example, 3.4.x -> 3.5.0

For bump major:

  • The current process does not directly support this scenario
  • A major release process should be discussed and designed separately, for example by introducing an additional branch or a new preparation flow

Release Principles

  • Daily development happens on main
  • Official releases are made only from release/X.Y
  • Official tags must use vX.Y.Z
  • Do not create official release tags on main

Standard Release Process

1. Confirm the release target

First confirm which release line this release belongs to and what the target version is.

Examples:

  • Release 3.4.1 on release/3.4
  • Release 3.5.0 on release/3.5

2. Create or switch to the release branch

If the release line does not exist yet, create the corresponding release/X.Y branch from main.
If it already exists, switch to that branch and continue release preparation there.

Requirements:

  • One minor release line corresponds to one fixed release/X.Y branch
  • That branch should contain only the release content and patch fixes for that line

3. Pick release content from main

Based on the release scope, cherry-pick the required commits from main into release/X.Y until the release content is ready.

Requirements:

  • Only pick what is needed for the current release
  • Avoid bringing unrelated new features into the release branch
  • If there are release-specific fixes on the release branch, keep them limited to the current release scope

4. Complete pre-release checks

Complete pre-release checks on release/X.Y.

At minimum, this should include:

  • The current branch is correct
  • The working tree is clean
  • The version is as expected
  • Key functionality is verified
  • Required tests, builds, packaging, and regression checks have passed
  • Release notes are ready

5. Create the official tag

Once the release is ready, create the official tag on release/X.Y:

  • The tag format must be vX.Y.Z

Examples:

  • v3.4.1
  • v3.5.0

Requirements:

  • The tag must be created on the release branch for the current official release
  • Do not use development tags as official release tags

6. Publish the GitHub Release

Create a GitHub Release based on the official tag for this release.

7. Update dependency constraints and release notes

If this release is the first release of a new minor line, or if it changes PaddleX dependency requirements, update the related release materials before or after the official tag is published.

At minimum, this should include:

  • Checking whether the paddlex dependency constraints in pyproject.toml match the target release
  • Checking whether installation docs, upgrade notes, and release notes are aligned with the release version

Completion criteria:

  • The paddlex dependency constraints match the target release
  • The version information in the documentation matches the released version

8. Sync the release branch lineage back to main

After the first official release of a new release/X.Y line is completed, sync the lineage of that release/X.Y branch back to main.

This is a fixed step in the current workflow and should be done at least once for each new minor release line.

Purpose:

  • Ensure main correctly reflects that the release line has produced an official version
  • Keep subsequent development and release cadence aligned

Requirements:

  • Perform this once after the first official release of each new release/X.Y
  • For later patch releases on the same release/X.Y, it is usually not necessary to repeat it

9. Move on to the next development cycle or patch release

After the release:

  • main continues with ongoing development
  • release/X.Y continues to maintain that release line

If more patch releases are needed later on the same line:

  • Continue preparing patches on release/X.Y
  • cherry-pick from main as needed
  • Repeat the relevant steps in this SOP

How to Handle Different Bump Types

Patch Release

Applicable scenarios:

  • Fixing production issues
  • Small compatibility fixes
  • Documentation, dependency, or stability patches

How to handle it:

  • Continue preparing changes on the existing release/X.Y
  • Create the next patch tag, for example v3.4.2

Minor Release

Applicable scenarios:

  • Starting a new release line
  • Releasing the next stable version, for example 3.5.0

How to handle it:

  • Create a new release/X.Y from main
  • Prepare the release following the standard process
  • Create the first official tag, for example v3.5.0
  • Update paddlex dependency constraints if needed
  • Sync the lineage of that release branch back to main after the release

Major Release

Current conclusion:

  • It is not included in this SOP for now
  • A separate process needs to be discussed and designed later

Before a dedicated solution is defined, do not directly reuse the current minor/patch process for a major release.

Release Checklist

Before each release, confirm the following:

  • The target version and corresponding release branch have been confirmed
  • The content on the release branch is ready
  • The release scope has been finalized
  • Key tests and regression checks have passed
  • Release notes are ready
  • The official tag uses the vX.Y.Z format
  • The GitHub Release has been created
  • If this is the first official release on release/X.Y, its lineage has been synced back to main

Daily Maintenance Recommendations

  • New features should go to main first
  • Official releases should always be performed through release/X.Y
  • Patch releases should always be maintained on the corresponding release/X.Y
  • For each new release/X.Y, sync its lineage once after the first official release

If the current process changes, this document should be updated accordingly.