diff options
| author | Andrew Godwin <andrew@aeracode.org> | 2013-04-18 17:16:39 +0100 |
|---|---|---|
| committer | Andrew Godwin <andrew@aeracode.org> | 2013-04-18 17:16:39 +0100 |
| commit | 7f3678dc4cd7146c49bac3fb8f5211f647636aa3 (patch) | |
| tree | fdd2a60ccd1a9a3162d89f970db44502e35a3b3f /docs/internals | |
| parent | b62e82365ad56ca930f7abb1d1dbdf9ce5a7c7c3 (diff) | |
| parent | 93c1576f17f6c5ee73f94f8de007f3c33010dc81 (diff) | |
Merge branch 'master' into schema-alteration
Conflicts:
django/db/backends/__init__.py
django/db/backends/mysql/base.py
django/db/backends/oracle/base.py
django/db/backends/oracle/creation.py
django/db/backends/postgresql_psycopg2/base.py
django/db/backends/sqlite3/base.py
django/db/models/fields/related.py
Diffstat (limited to 'docs/internals')
| -rw-r--r-- | docs/internals/_images/djangotickets.png | bin | 52003 -> 0 bytes | |||
| -rw-r--r-- | docs/internals/_images/triage_process.graffle | 2141 | ||||
| -rw-r--r-- | docs/internals/_images/triage_process.pdf | bin | 0 -> 59051 bytes | |||
| -rw-r--r-- | docs/internals/_images/triage_process.svg | 3 | ||||
| -rw-r--r-- | docs/internals/committers.txt | 34 | ||||
| -rw-r--r-- | docs/internals/contributing/committing-code.txt | 2 | ||||
| -rw-r--r-- | docs/internals/contributing/new-contributors.txt | 9 | ||||
| -rw-r--r-- | docs/internals/contributing/triaging-tickets.txt | 150 | ||||
| -rw-r--r-- | docs/internals/contributing/writing-code/coding-style.txt | 23 | ||||
| -rw-r--r-- | docs/internals/contributing/writing-code/submitting-patches.txt | 6 | ||||
| -rw-r--r-- | docs/internals/contributing/writing-code/unit-tests.txt | 34 | ||||
| -rw-r--r-- | docs/internals/contributing/writing-code/working-with-git.txt | 4 | ||||
| -rw-r--r-- | docs/internals/deprecation.txt | 149 | ||||
| -rw-r--r-- | docs/internals/git.txt | 2 | ||||
| -rw-r--r-- | docs/internals/howto-release-django.txt | 320 | ||||
| -rw-r--r-- | docs/internals/index.txt | 1 | ||||
| -rw-r--r-- | docs/internals/release-process.txt | 156 |
17 files changed, 2811 insertions, 223 deletions
diff --git a/docs/internals/_images/djangotickets.png b/docs/internals/_images/djangotickets.png Binary files differdeleted file mode 100644 index 34a2a41852..0000000000 --- a/docs/internals/_images/djangotickets.png +++ /dev/null diff --git a/docs/internals/_images/triage_process.graffle b/docs/internals/_images/triage_process.graffle new file mode 100644 index 0000000000..291c0397f7 --- /dev/null +++ b/docs/internals/_images/triage_process.graffle @@ -0,0 +1,2141 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>ActiveLayerIndex</key> + <integer>0</integer> + <key>ApplicationVersion</key> + <array> + <string>com.omnigroup.OmniGrafflePro</string> + <string>139.16.0.171715</string> + </array> + <key>AutoAdjust</key> + <true/> + <key>BackgroundGraphic</key> + <dict> + <key>Bounds</key> + <string>{{0, 0}, {559.28997802734375, 782.8900146484375}}</string> + <key>Class</key> + <string>SolidGraphic</string> + <key>ID</key> + <integer>2</integer> + <key>Style</key> + <dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + </dict> + <key>BaseZoom</key> + <integer>0</integer> + <key>CanvasOrigin</key> + <string>{0, 0}</string> + <key>ColumnAlign</key> + <integer>1</integer> + <key>ColumnSpacing</key> + <real>36</real> + <key>CreationDate</key> + <string>2012-12-22 15:48:38 +0000</string> + <key>Creator</key> + <string>Aymeric Augustin</string> + <key>DisplayScale</key> + <string>1.000 cm = 1.000 cm</string> + <key>GraphDocumentVersion</key> + <integer>8</integer> + <key>GraphicsList</key> + <array> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>132</integer> + </dict> + <key>ID</key> + <integer>151</integer> + <key>Points</key> + <array> + <string>{252, 288}</string> + <string>{315, 324}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0.501961</string> + <key>r</key> + <string>0</string> + </dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>2</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>82</integer> + <key>Info</key> + <integer>1</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>104</integer> + <key>OrthogonalBarAutomatic</key> + <true/> + <key>OrthogonalBarPoint</key> + <string>{0, 0}</string> + <key>OrthogonalBarPosition</key> + <real>-1</real> + <key>Points</key> + <array> + <string>{134.4999955076145, 414}</string> + <string>{90, 414}</string> + <string>{81, 522}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.6</string> + </dict> + <key>HeadArrow</key> + <string>0</string> + <key>Legacy</key> + <true/> + <key>LineType</key> + <integer>2</integer> + <key>Pattern</key> + <integer>1</integer> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>103</integer> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{135, 405}, {18, 18}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>103</integer> + <key>Shape</key> + <string>Circle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.6</string> + </dict> + <key>Pattern</key> + <integer>1</integer> + </dict> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{72, 522}, {342, 36}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>HFlip</key> + <string>YES</string> + <key>ID</key> + <integer>102</integer> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.6</string> + </dict> + <key>Pattern</key> + <integer>1</integer> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Pad</key> + <integer>4</integer> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red102\green102\blue102;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\i\fs24 \cf2 The ticket has a patch which applies cleanly and includes all needed tests and docs. A core developer can commit it as is.}</string> + </dict> + <key>VFlip</key> + <string>YES</string> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>98</integer> + <key>OrthogonalBarAutomatic</key> + <true/> + <key>OrthogonalBarPoint</key> + <string>{0, 0}</string> + <key>OrthogonalBarPosition</key> + <real>-1</real> + <key>Points</key> + <array> + <string>{134.4999955076145, 324}</string> + <string>{90, 324}</string> + <string>{81, 198}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.6</string> + </dict> + <key>HeadArrow</key> + <string>0</string> + <key>Legacy</key> + <true/> + <key>LineType</key> + <integer>2</integer> + <key>Pattern</key> + <integer>1</integer> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>97</integer> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{135, 315}, {18, 18}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>97</integer> + <key>Shape</key> + <string>Circle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.6</string> + </dict> + <key>Pattern</key> + <integer>1</integer> + </dict> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{72, 144}, {99, 54}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>HFlip</key> + <string>YES</string> + <key>ID</key> + <integer>96</integer> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.6</string> + </dict> + <key>Pattern</key> + <integer>1</integer> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Pad</key> + <integer>4</integer> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red102\green102\blue102;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\i\fs24 \cf2 The ticket is a bug and should be fixed.}</string> + </dict> + <key>VFlip</key> + <string>YES</string> + </dict> + <dict> + <key>Bounds</key> + <string>{{243, 279}, {18, 18}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>ID</key> + <integer>91</integer> + <key>Shape</key> + <string>Circle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.6</string> + </dict> + <key>Pattern</key> + <integer>1</integer> + </dict> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>90</integer> + <key>Points</key> + <array> + <string>{252, 278.49999548068274}</string> + <string>{252, 198}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.6</string> + </dict> + <key>HeadArrow</key> + <string>0</string> + <key>Legacy</key> + <true/> + <key>LineType</key> + <integer>1</integer> + <key>Pattern</key> + <integer>1</integer> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>91</integer> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{189, 144}, {243, 54}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>HFlip</key> + <string>YES</string> + <key>ID</key> + <integer>89</integer> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.6</string> + <key>g</key> + <string>0.6</string> + <key>r</key> + <string>0.6</string> + </dict> + <key>Pattern</key> + <integer>1</integer> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Pad</key> + <integer>4</integer> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red102\green102\blue102;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\i\fs24 \cf2 The ticket was already reported, was already rejected, isn't a bug, doesn't contain enough information, or can't be reproduced.}</string> + </dict> + <key>VFlip</key> + <string>YES</string> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>10</integer> + </dict> + <key>ID</key> + <integer>60</integer> + <key>Points</key> + <array> + <string>{144, 396}</string> + <string>{144, 450}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0.501961</string> + <key>r</key> + <string>0</string> + </dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>2</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>11</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>82</integer> + <key>Points</key> + <array> + <string>{198, 288}</string> + <string>{252, 288}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0.501961</string> + <key>r</key> + <string>0</string> + </dict> + <key>HeadArrow</key> + <string>0</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>2</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>12</integer> + <key>Info</key> + <integer>3</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>11</integer> + </dict> + <key>ID</key> + <integer>54</integer> + <key>Points</key> + <array> + <string>{144, 306}</string> + <string>{144, 360}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0.501961</string> + <key>r</key> + <string>0</string> + </dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>2</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>12</integer> + <key>Info</key> + <integer>1</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>130</integer> + </dict> + <key>ID</key> + <integer>131</integer> + <key>Points</key> + <array> + <string>{198, 468}</string> + <string>{315, 468}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.501961</string> + <key>g</key> + <string>0.25098</string> + <key>r</key> + <string>0</string> + </dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>2</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>10</integer> + <key>Info</key> + <integer>3</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>135</integer> + <key>Info</key> + <integer>4</integer> + </dict> + <key>ID</key> + <integer>136</integer> + <key>Points</key> + <array> + <string>{252, 288}</string> + <string>{315, 432}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0.501961</string> + <key>r</key> + <string>0</string> + </dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>2</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>82</integer> + <key>Info</key> + <integer>1</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>137</integer> + <key>Info</key> + <integer>4</integer> + </dict> + <key>ID</key> + <integer>138</integer> + <key>Points</key> + <array> + <string>{252, 288}</string> + <string>{315, 396}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0.501961</string> + <key>r</key> + <string>0</string> + </dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>2</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>82</integer> + <key>Info</key> + <integer>1</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>139</integer> + <key>Info</key> + <integer>4</integer> + </dict> + <key>ID</key> + <integer>140</integer> + <key>Points</key> + <array> + <string>{252, 288}</string> + <string>{315, 360}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0.501961</string> + <key>r</key> + <string>0</string> + </dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>2</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>82</integer> + <key>Info</key> + <integer>1</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>Head</key> + <dict> + <key>ID</key> + <integer>123</integer> + <key>Info</key> + <integer>4</integer> + </dict> + <key>ID</key> + <integer>124</integer> + <key>Points</key> + <array> + <string>{252, 288}</string> + <string>{315, 288}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0.501961</string> + <key>r</key> + <string>0</string> + </dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>2</real> + </dict> + </dict> + <key>Tail</key> + <dict> + <key>ID</key> + <integer>82</integer> + <key>Info</key> + <integer>1</integer> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{270, 576}, {81, 18}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica-Bold</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>128</integer> + <key>Magnets</key> + <array> + <string>{0, 1}</string> + <string>{0, -1}</string> + <string>{1, 0}</string> + <string>{-1, 0}</string> + </array> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>GradientCenter</key> + <string>{0, 0.15238095234285712}</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\i\fs24 \cf0 status}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{72.000000000000057, 596}, {99, 14}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FitText</key> + <string>Vertical</string> + <key>Flow</key> + <string>Resize</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>45</integer> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>2</integer> + <key>Pad</key> + <integer>0</integer> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red0\green64\blue128;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qr + +\f0\b\fs24 \cf2 Committers}</string> + <key>VerticalPad</key> + <integer>0</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>44</integer> + <key>Points</key> + <array> + <string>{183.59999999999997, 603}</string> + <string>{221.39999999999998, 603}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0.501961</string> + <key>g</key> + <string>0.25098</string> + <key>r</key> + <string>0</string> + </dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>Legacy</key> + <true/> + <key>LineType</key> + <integer>1</integer> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>2</real> + </dict> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{72.000000000000057, 578}, {99, 14}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FitText</key> + <string>Vertical</string> + <key>Flow</key> + <string>Resize</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>43</integer> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Align</key> + <integer>2</integer> + <key>Pad</key> + <integer>0</integer> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;\red0\green128\blue0;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qr + +\f0\b\fs24 \cf2 Ticket triagers }</string> + <key>VerticalPad</key> + <integer>0</integer> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>42</integer> + <key>Points</key> + <array> + <string>{183.59999999999997, 585}</string> + <string>{221.39999999999998, 585}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>Color</key> + <dict> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0.501961</string> + <key>r</key> + <string>0</string> + </dict> + <key>HeadArrow</key> + <string>FilledArrow</string> + <key>Legacy</key> + <true/> + <key>LineType</key> + <integer>1</integer> + <key>TailArrow</key> + <string>0</string> + <key>Width</key> + <real>2</real> + </dict> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{270, 594}, {81, 18}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica-Bold</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>129</integer> + <key>Magnets</key> + <array> + <string>{0, 1}</string> + <string>{0, -1}</string> + <string>{1, 0}</string> + <string>{-1, 0}</string> + </array> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>a</key> + <string>0.3</string> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.501961</string> + <key>r</key> + <string>0</string> + </dict> + <key>GradientCenter</key> + <string>{0, 0.15238095234285712}</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 in progress}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{351, 576}, {81, 18}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica-Bold</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>125</integer> + <key>Magnets</key> + <array> + <string>{0, 1}</string> + <string>{0, -1}</string> + <string>{1, 0}</string> + <string>{-1, 0}</string> + </array> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>a</key> + <string>0.3</string> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0</string> + <key>r</key> + <string>1</string> + </dict> + <key>GradientCenter</key> + <string>{0, 0.15238095234285712}</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 stopped}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{351, 594}, {81, 18}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica-Bold</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>127</integer> + <key>Magnets</key> + <array> + <string>{0, 1}</string> + <string>{0, -1}</string> + <string>{1, 0}</string> + <string>{-1, 0}</string> + </array> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>a</key> + <string>0.3</string> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0.501961</string> + <key>r</key> + <string>0</string> + </dict> + <key>GradientCenter</key> + <string>{0, 0.15238095234285712}</string> + </dict> + <key>shadow</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 completed}</string> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>36</integer> + <key>Points</key> + <array> + <string>{288, 243}</string> + <string>{432, 243}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>0</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + </dict> + <dict> + <key>Class</key> + <string>LineGraphic</string> + <key>ID</key> + <integer>33</integer> + <key>Points</key> + <array> + <string>{72, 243}</string> + <string>{216, 243}</string> + </array> + <key>Style</key> + <dict> + <key>stroke</key> + <dict> + <key>HeadArrow</key> + <string>0</string> + <key>Legacy</key> + <true/> + <key>TailArrow</key> + <string>0</string> + </dict> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{315, 315}, {90.000000000000014, 18}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica-Bold</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>132</integer> + <key>Magnets</key> + <array> + <string>{0, 1}</string> + <string>{0, -1}</string> + <string>{1, 0}</string> + <string>{-1, 0}</string> + </array> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>a</key> + <string>0.3</string> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0</string> + <key>r</key> + <string>1</string> + </dict> + <key>GradientCenter</key> + <string>{0, 0.15238095234285712}</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 wontfix}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{315, 423}, {90.000000000000014, 18}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica-Bold</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>135</integer> + <key>Magnets</key> + <array> + <string>{0, 1}</string> + <string>{0, -1}</string> + <string>{1, 0}</string> + <string>{-1, 0}</string> + </array> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>a</key> + <string>0.3</string> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0</string> + <key>r</key> + <string>1</string> + </dict> + <key>GradientCenter</key> + <string>{0, 0.15238095234285712}</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 worksforme}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{315, 387}, {90.000000000000014, 18}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica-Bold</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>137</integer> + <key>Magnets</key> + <array> + <string>{0, 1}</string> + <string>{0, -1}</string> + <string>{1, 0}</string> + <string>{-1, 0}</string> + </array> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>a</key> + <string>0.3</string> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0</string> + <key>r</key> + <string>1</string> + </dict> + <key>GradientCenter</key> + <string>{0, 0.15238095234285712}</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 needsinfo}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{315, 351}, {90.000000000000014, 18}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica-Bold</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>139</integer> + <key>Magnets</key> + <array> + <string>{0, 1}</string> + <string>{0, -1}</string> + <string>{1, 0}</string> + <string>{-1, 0}</string> + </array> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>a</key> + <string>0.3</string> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0</string> + <key>r</key> + <string>1</string> + </dict> + <key>GradientCenter</key> + <string>{0, 0.15238095234285712}</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 invalid}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{315, 459}, {90.000000000000014, 18}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica-Bold</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>130</integer> + <key>Magnets</key> + <array> + <string>{0, 1}</string> + <string>{0, -1}</string> + <string>{1, 0}</string> + <string>{-1, 0}</string> + </array> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>a</key> + <string>0.3</string> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0.501961</string> + <key>r</key> + <string>0</string> + </dict> + <key>GradientCenter</key> + <string>{0, 0.15238095234285712}</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 fixed}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{315, 279}, {90.000000000000014, 18}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica-Bold</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>123</integer> + <key>Magnets</key> + <array> + <string>{0, 1}</string> + <string>{0, -1}</string> + <string>{1, 0}</string> + <string>{-1, 0}</string> + </array> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>a</key> + <string>0.3</string> + <key>b</key> + <string>0</string> + <key>g</key> + <string>0</string> + <key>r</key> + <string>1</string> + </dict> + <key>GradientCenter</key> + <string>{0, 0.15238095234285712}</string> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 duplicate}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{90, 270}, {108, 36}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>12</integer> + <key>Magnets</key> + <array> + <string>{0, 1}</string> + <string>{0, -1}</string> + <string>{1, 0}</string> + <string>{-1, 0}</string> + </array> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>a</key> + <string>0.3</string> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.501961</string> + <key>r</key> + <string>0</string> + </dict> + </dict> + <key>stroke</key> + <dict> + <key>CornerRadius</key> + <real>5</real> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Unreviewed}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{90, 360}, {108, 36}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>11</integer> + <key>Magnets</key> + <array> + <string>{0, 1}</string> + <string>{0, -1}</string> + <string>{1, 0}</string> + <string>{-1, 0}</string> + </array> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>a</key> + <string>0.3</string> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.501961</string> + <key>r</key> + <string>0</string> + </dict> + </dict> + <key>stroke</key> + <dict> + <key>CornerRadius</key> + <real>5</real> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Accepted}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{90, 450}, {108, 36}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>10</integer> + <key>Magnets</key> + <array> + <string>{0, 1}</string> + <string>{0, -1}</string> + <string>{1, 0}</string> + <string>{-1, 0}</string> + </array> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>Color</key> + <dict> + <key>a</key> + <string>0.3</string> + <key>b</key> + <string>1</string> + <key>g</key> + <string>0.501961</string> + <key>r</key> + <string>0</string> + </dict> + </dict> + <key>stroke</key> + <dict> + <key>CornerRadius</key> + <real>5</real> + </dict> + </dict> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs24 \cf0 Ready for Checkin}</string> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{72, 216}, {144, 288}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>13</real> + </dict> + <key>ID</key> + <integer>99</integer> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict/> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs28 \cf0 Open tickets\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\fs12 \cf0 \ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\i\fs24 \cf0 triage state}</string> + </dict> + <key>TextPlacement</key> + <integer>0</integer> + </dict> + <dict> + <key>Bounds</key> + <string>{{288, 216}, {144, 288}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>15</real> + </dict> + <key>ID</key> + <integer>32</integer> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict/> + <key>Text</key> + <dict> + <key>Text</key> + <string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf370 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\f0\fs28 \cf0 Closed tickets\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\fs12 \cf0 \ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc + +\i\fs24 \cf0 resolution}</string> + </dict> + <key>TextPlacement</key> + <integer>0</integer> + </dict> + <dict> + <key>Bounds</key> + <string>{{270, 576}, {162, 36}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica-Bold</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>126</integer> + <key>Magnets</key> + <array> + <string>{0, 1}</string> + <string>{0, -1}</string> + <string>{1, 0}</string> + <string>{-1, 0}</string> + </array> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>GradientCenter</key> + <string>{0, 0.15238095234285712}</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + </dict> + <dict> + <key>Bounds</key> + <string>{{72, 576}, {162, 36}}</string> + <key>Class</key> + <string>ShapedGraphic</string> + <key>FontInfo</key> + <dict> + <key>Font</key> + <string>Helvetica</string> + <key>Size</key> + <real>12</real> + </dict> + <key>ID</key> + <integer>88</integer> + <key>Magnets</key> + <array> + <string>{0, 1}</string> + <string>{0, -1}</string> + <string>{1, 0}</string> + <string>{-1, 0}</string> + </array> + <key>Shape</key> + <string>Rectangle</string> + <key>Style</key> + <dict> + <key>fill</key> + <dict> + <key>GradientCenter</key> + <string>{0, 0.15238095234285712}</string> + </dict> + <key>stroke</key> + <dict> + <key>Draws</key> + <string>NO</string> + </dict> + </dict> + </dict> + </array> + <key>GridInfo</key> + <dict> + <key>ShowsGrid</key> + <string>YES</string> + <key>SnapsToGrid</key> + <string>YES</string> + </dict> + <key>GuidesLocked</key> + <string>NO</string> + <key>GuidesVisible</key> + <string>YES</string> + <key>HPages</key> + <integer>1</integer> + <key>ImageCounter</key> + <integer>1</integer> + <key>KeepToScale</key> + <false/> + <key>Layers</key> + <array> + <dict> + <key>Lock</key> + <string>NO</string> + <key>Name</key> + <string>Calque 1</string> + <key>Print</key> + <string>YES</string> + <key>View</key> + <string>YES</string> + </dict> + </array> + <key>LayoutInfo</key> + <dict> + <key>Animate</key> + <string>NO</string> + <key>circoMinDist</key> + <real>18</real> + <key>circoSeparation</key> + <real>0.0</real> + <key>layoutEngine</key> + <string>dot</string> + <key>neatoSeparation</key> + <real>0.0</real> + <key>twopiSeparation</key> + <real>0.0</real> + </dict> + <key>LinksVisible</key> + <string>NO</string> + <key>MagnetsVisible</key> + <string>NO</string> + <key>MasterSheets</key> + <array/> + <key>ModificationDate</key> + <string>2013-04-08 16:32:00 +0000</string> + <key>Modifier</key> + <string>Aymeric Augustin</string> + <key>NotesVisible</key> + <string>NO</string> + <key>Orientation</key> + <integer>2</integer> + <key>OriginVisible</key> + <string>NO</string> + <key>PageBreaks</key> + <string>YES</string> + <key>PrintInfo</key> + <dict> + <key>NSBottomMargin</key> + <array> + <string>float</string> + <string>41</string> + </array> + <key>NSHorizonalPagination</key> + <array> + <string>coded</string> + <string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG</string> + </array> + <key>NSLeftMargin</key> + <array> + <string>float</string> + <string>18</string> + </array> + <key>NSPaperSize</key> + <array> + <string>size</string> + <string>{595.28997802734375, 841.8900146484375}</string> + </array> + <key>NSPrintReverseOrientation</key> + <array> + <string>int</string> + <string>0</string> + </array> + <key>NSRightMargin</key> + <array> + <string>float</string> + <string>18</string> + </array> + <key>NSTopMargin</key> + <array> + <string>float</string> + <string>18</string> + </array> + </dict> + <key>PrintOnePage</key> + <false/> + <key>ReadOnly</key> + <string>NO</string> + <key>RowAlign</key> + <integer>1</integer> + <key>RowSpacing</key> + <real>36</real> + <key>SheetTitle</key> + <string>Canevas 1</string> + <key>SmartAlignmentGuidesActive</key> + <string>YES</string> + <key>SmartDistanceGuidesActive</key> + <string>YES</string> + <key>UniqueID</key> + <integer>1</integer> + <key>UseEntirePage</key> + <false/> + <key>VPages</key> + <integer>1</integer> + <key>WindowInfo</key> + <dict> + <key>CurrentSheet</key> + <integer>0</integer> + <key>ExpandedCanvases</key> + <array/> + <key>Frame</key> + <string>{{1, 4}, {1190, 874}}</string> + <key>ListView</key> + <true/> + <key>OutlineWidth</key> + <integer>142</integer> + <key>RightSidebar</key> + <false/> + <key>ShowRuler</key> + <true/> + <key>Sidebar</key> + <true/> + <key>SidebarWidth</key> + <integer>120</integer> + <key>VisibleRegion</key> + <string>{{-195, 118.01801649706192}, {950.4504382015291, 662.16215362855348}}</string> + <key>Zoom</key> + <real>1.1100000143051147</real> + <key>ZoomValues</key> + <array> + <array> + <string>Canevas 1</string> + <real>1.1100000143051147</real> + <real>1.0499999523162842</real> + </array> + </array> + </dict> +</dict> +</plist> diff --git a/docs/internals/_images/triage_process.pdf b/docs/internals/_images/triage_process.pdf Binary files differnew file mode 100644 index 0000000000..f731e3e584 --- /dev/null +++ b/docs/internals/_images/triage_process.pdf diff --git a/docs/internals/_images/triage_process.svg b/docs/internals/_images/triage_process.svg new file mode 100644 index 0000000000..787f5ca647 --- /dev/null +++ b/docs/internals/_images/triage_process.svg @@ -0,0 +1,3 @@ +<?xml version="1.0"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="52 133 400 501" width="400pt" height="501pt"><metadata xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:date>2013-04-08 16:32Z</dc:date><!-- Produced by OmniGraffle Professional 5.4.2 --></metadata><defs><filter id="Shadow" filterUnits="userSpaceOnUse"><feGaussianBlur in="SourceAlpha" result="blur" stdDeviation="3.488"/><feOffset in="blur" result="offset" dx="0" dy="4"/><feFlood flood-color="black" flood-opacity=".75" result="flood"/><feComposite in="flood" in2="offset" operator="in"/></filter><font-face font-family="Helvetica" font-size="14" units-per-em="1000" underline-position="-75.683594" underline-thickness="49.316406" slope="0" x-height="522.94922" cap-height="717.28516" ascent="770.01953" descent="-229.98047" font-weight="500"><font-face-src><font-face-name name="Helvetica"/></font-face-src></font-face><font-face font-family="Helvetica" font-size="12" units-per-em="1000" underline-position="-75.683594" underline-thickness="49.316406" slope="-1e3" x-height="522.94922" cap-height="717.28516" ascent="770.01953" descent="-229.98047" font-style="italic" font-weight="500"><font-face-src><font-face-name name="Helvetica-Oblique"/></font-face-src></font-face><font-face font-family="Helvetica" font-size="12" units-per-em="1000" underline-position="-75.683594" underline-thickness="49.316406" slope="0" x-height="522.94922" cap-height="717.28516" ascent="770.01953" descent="-229.98047" font-weight="500"><font-face-src><font-face-name name="Helvetica"/></font-face-src></font-face><marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" viewBox="-1 -3 7 6" markerWidth="7" markerHeight="6" color="green"><g><path d="M 4.8000002 0 L 0 -1.8000001 L 0 1.8000001 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/></g></marker><font-face font-family="Helvetica" font-size="12" units-per-em="1000" underline-position="-75.683594" underline-thickness="49.316406" slope="0" x-height="532.22656" cap-height="719.72656" ascent="770.01953" descent="-229.98047" font-weight="bold"><font-face-src><font-face-name name="Helvetica-Bold"/></font-face-src></font-face><marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker_2" viewBox="-1 -3 7 6" markerWidth="7" markerHeight="6" color="#004080"><g><path d="M 4.8000002 0 L 0 -1.8000001 L 0 1.8000001 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/></g></marker></defs><g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1"><title>Canevas 1</title><rect fill="white" width="559.28998" height="782.89"/><g><title>Calque 1</title><g><use xl:href="#id88_Graphic" filter="url(#Shadow)"/><use xl:href="#id126_Graphic" filter="url(#Shadow)"/><use xl:href="#id32_Graphic" filter="url(#Shadow)"/><use xl:href="#id99_Graphic" filter="url(#Shadow)"/><use xl:href="#id10_Graphic" filter="url(#Shadow)"/><use xl:href="#id11_Graphic" filter="url(#Shadow)"/><use xl:href="#id12_Graphic" filter="url(#Shadow)"/><use xl:href="#id123_Graphic" filter="url(#Shadow)"/><use xl:href="#id130_Graphic" filter="url(#Shadow)"/><use xl:href="#id139_Graphic" filter="url(#Shadow)"/><use xl:href="#id137_Graphic" filter="url(#Shadow)"/><use xl:href="#id135_Graphic" filter="url(#Shadow)"/><use xl:href="#id132_Graphic" filter="url(#Shadow)"/></g><g id="id88_Graphic"><rect x="72" y="576" width="162" height="36" fill="white"/></g><g id="id126_Graphic"><rect x="270" y="576" width="162" height="36" fill="white"/></g><g id="id32_Graphic"><rect x="288" y="216" width="144" height="288" fill="white"/><rect x="288" y="216" width="144" height="288" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(293 221)" fill="black"><tspan font-family="Helvetica" font-size="14" font-weight="500" x="23.427734" y="14" textLength="87.14453">Closed tickets</tspan><tspan font-family="Helvetica" font-size="12" font-style="italic" font-weight="500" x="40.984375" y="35" textLength="52.03125">resolution</tspan></text></g><g id="id99_Graphic"><rect x="72" y="216" width="144" height="288" fill="white"/><rect x="72" y="216" width="144" height="288" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(77 221)" fill="black"><tspan font-family="Helvetica" font-size="14" font-weight="500" x="28.093262" y="14" textLength="77.813477">Open tickets</tspan><tspan font-family="Helvetica" font-size="12" font-style="italic" font-weight="500" x="37.316406" y="35" textLength="59.367188">triage state</tspan></text></g><g id="id10_Graphic"><path d="M 95 450 L 193 450 C 195.76142 450 198 452.23858 198 455 L 198 481 C 198 483.76142 195.76142 486 193 486 L 95 486 C 92.238576 486 90 483.76142 90 481 C 90 481 90 481 90 481 L 90 455 C 90 452.23858 92.238576 450 95 450 C 95 450 95 450 95 450 Z" fill="#0080ff" fill-opacity=".30000001"/><path d="M 95 450 L 193 450 C 195.76142 450 198 452.23858 198 455 L 198 481 C 198 483.76142 195.76142 486 193 486 L 95 486 C 92.238576 486 90 483.76142 90 481 C 90 481 90 481 90 481 L 90 455 C 90 452.23858 92.238576 450 95 450 C 95 450 95 450 95 450 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(95 454)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="22.987305" y="11" textLength="55.359375">Ready for </tspan><tspan font-family="Helvetica" font-size="12" font-weight="500" x="27.323242" y="25" textLength="43.353516">Checkin</tspan></text></g><g id="id11_Graphic"><path d="M 95 360 L 193 360 C 195.76142 360 198 362.23858 198 365 L 198 391 C 198 393.76142 195.76142 396 193 396 L 95 396 C 92.238576 396 90 393.76142 90 391 C 90 391 90 391 90 391 L 90 365 C 90 362.23858 92.238576 360 95 360 C 95 360 95 360 95 360 Z" fill="#0080ff" fill-opacity=".30000001"/><path d="M 95 360 L 193 360 C 195.76142 360 198 362.23858 198 365 L 198 391 C 198 393.76142 195.76142 396 193 396 L 95 396 C 92.238576 396 90 393.76142 90 391 C 90 391 90 391 90 391 L 90 365 C 90 362.23858 92.238576 360 95 360 C 95 360 95 360 95 360 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(95 371)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="23.983398" y="11" textLength="50.033203">Accepted</tspan></text></g><g id="id12_Graphic"><path d="M 95 270 L 193 270 C 195.76142 270 198 272.23858 198 275 L 198 301 C 198 303.76142 195.76142 306 193 306 L 95 306 C 92.238576 306 90 303.76142 90 301 C 90 301 90 301 90 301 L 90 275 C 90 272.23858 92.238576 270 95 270 C 95 270 95 270 95 270 Z" fill="#0080ff" fill-opacity=".30000001"/><path d="M 95 270 L 193 270 C 195.76142 270 198 272.23858 198 275 L 198 301 C 198 303.76142 195.76142 306 193 306 L 95 306 C 92.238576 306 90 303.76142 90 301 C 90 301 90 301 90 301 L 90 275 C 90 272.23858 92.238576 270 95 270 C 95 270 95 270 95 270 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(95 281)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="17.318359" y="11" textLength="63.36328">Unreviewed</tspan></text></g><g id="id123_Graphic"><rect x="315" y="279" width="90" height="18" fill="red" fill-opacity=".30000001"/><rect x="315" y="279" width="90" height="18" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(320 281)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="15.982422" y="11" textLength="48.035156">duplicate</tspan></text></g><g id="id130_Graphic"><rect x="315" y="459" width="90" height="18" fill="green" fill-opacity=".30000001"/><rect x="315" y="459" width="90" height="18" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(320 461)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="27.326172" y="11" textLength="6">fi</tspan><tspan font-family="Helvetica" font-size="12" font-weight="500" x="33.326172" y="11" textLength="19.347656">xed</tspan></text></g><g id="id139_Graphic"><rect x="315" y="351" width="90" height="18" fill="red" fill-opacity=".30000001"/><rect x="315" y="351" width="90" height="18" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(320 353)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="22.990234" y="11" textLength="34.019531">invalid</tspan></text></g><g id="id137_Graphic"><rect x="315" y="387" width="90" height="18" fill="red" fill-opacity=".30000001"/><rect x="315" y="387" width="90" height="18" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(320 389)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="13.978516" y="11" textLength="52.04297">needsinfo</tspan></text></g><g id="id135_Graphic"><rect x="315" y="423" width="90" height="18" fill="red" fill-opacity=".30000001"/><rect x="315" y="423" width="90" height="18" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(320 425)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="8.995117" y="11" textLength="62.009766">worksforme</tspan></text></g><g id="id132_Graphic"><rect x="315" y="315" width="90" height="18" fill="red" fill-opacity=".30000001"/><rect x="315" y="315" width="90" height="18" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><text transform="translate(320 317)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="21.326172" y="11" textLength="31.347656">wontfi</tspan><tspan font-family="Helvetica" font-size="12" font-weight="500" x="52.673828" y="11" textLength="6">x</tspan></text></g><line x1="72" y1="243" x2="216" y2="243" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><line x1="288" y1="243" x2="432" y2="243" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/><rect x="351" y="594" width="81" height="18" fill="green" fill-opacity=".30000001"/><text transform="translate(356 596)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="7.817383" y="11" textLength="55.365234">completed</tspan></text><rect x="351" y="576" width="81" height="18" fill="red" fill-opacity=".30000001"/><text transform="translate(356 578)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="14.1484375" y="11" textLength="42.703125">stopped</tspan></text><rect x="270" y="594" width="81" height="18" fill="#0080ff" fill-opacity=".30000001"/><text transform="translate(275 596)" fill="black"><tspan font-family="Helvetica" font-size="12" font-weight="500" x="5.819336" y="11" textLength="59.361328">in progress</tspan></text><line x1="183.6" y1="585" x2="208.5" y2="585" marker-end="url(#FilledArrow_Marker)" stroke="green" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><text transform="translate(72 578)" fill="green"><tspan font-family="Helvetica" font-size="12" font-weight="bold" fill="green" x="17.173828" y="11" textLength="7.330078">T</tspan><tspan font-family="Helvetica" font-size="12" font-weight="bold" fill="green" x="24.292969" y="11" textLength="78.041016">icket triagers </tspan></text><line x1="183.6" y1="603" x2="208.5" y2="603" marker-end="url(#FilledArrow_Marker_2)" stroke="#004080" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><text transform="translate(72 596)" fill="#004080"><tspan font-family="Helvetica" font-size="12" font-weight="bold" fill="#004080" x="32.320312" y="11" textLength="66.679688">Committers</tspan></text><rect x="270" y="576" width="81" height="18" fill="white"/><text transform="translate(275 578)" fill="black"><tspan font-family="Helvetica" font-size="12" font-style="italic" font-weight="500" x="19.492188" y="11" textLength="32.015625">status</tspan></text><line x1="252" y1="288" x2="302.1" y2="288" marker-end="url(#FilledArrow_Marker)" stroke="green" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><line x1="252" y1="288" x2="306.50529" y2="350.29176" marker-end="url(#FilledArrow_Marker)" stroke="green" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><line x1="252" y1="288" x2="308.50006" y2="384.85725" marker-end="url(#FilledArrow_Marker)" stroke="green" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><line x1="252" y1="288" x2="309.82944" y2="420.18157" marker-end="url(#FilledArrow_Marker)" stroke="green" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><line x1="198" y1="468" x2="302.1" y2="468" marker-end="url(#FilledArrow_Marker_2)" stroke="#004080" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><line x1="144" y1="306" x2="144" y2="347.1" marker-end="url(#FilledArrow_Marker)" stroke="green" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><line x1="198" y1="288" x2="252" y2="288" stroke="green" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><line x1="144" y1="396" x2="144" y2="437.1" marker-end="url(#FilledArrow_Marker)" stroke="green" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><rect x="189" y="144" width="243" height="54" fill="white"/><path d="M 432 198 L 189 198 L 189 144 L 432 144 Z" stroke="#999" stroke-linecap="round" stroke-linejoin="round" stroke-width="1" stroke-dasharray="4,4"/><text transform="translate(193 150)" fill="#666"><tspan font-family="Helvetica" font-size="12" font-style="italic" font-weight="500" fill="#666" x="19.789062" y="11" textLength="198.75586">The ticket was already reported, was </tspan><tspan font-family="Helvetica" font-size="12" font-style="italic" font-weight="500" fill="#666" x=".8017578" y="25" textLength="236.73047">already rejected, isn't a bug, doesn't contain </tspan><tspan font-family="Helvetica" font-size="12" font-style="italic" font-weight="500" fill="#666" x="1.2792969" y="39" textLength="232.4414">enough information, or can't be reproduced.</tspan></text><line x1="252" y1="278.5" x2="252" y2="198" stroke="#999" stroke-linecap="round" stroke-linejoin="round" stroke-width="1" stroke-dasharray="4,4"/><path d="M 258.36395 281.63605 C 261.87869 285.15076 261.87869 290.84924 258.36395 294.36395 C 254.84924 297.87869 249.15076 297.87869 245.63605 294.36395 C 242.12131 290.84924 242.12131 285.15076 245.63605 281.63605 C 249.15076 278.12131 254.84924 278.12131 258.36395 281.63605" stroke="#999" stroke-linecap="round" stroke-linejoin="round" stroke-width="1" stroke-dasharray="4,4"/><rect x="72" y="144" width="99" height="54" fill="white"/><path d="M 171 198 L 72 198 L 72 144 L 171 144 Z" stroke="#999" stroke-linecap="round" stroke-linejoin="round" stroke-width="1" stroke-dasharray="4,4"/><text transform="translate(76 150)" fill="#666"><tspan font-family="Helvetica" font-size="12" font-style="italic" font-weight="500" fill="#666" x="8.486328" y="11" textLength="77.36133">The ticket is a </tspan><tspan font-family="Helvetica" font-size="12" font-style="italic" font-weight="500" fill="#666" x="4.4638672" y="25" textLength="85.40625">bug and should </tspan><tspan font-family="Helvetica" font-size="12" font-style="italic" font-weight="500" fill="#666" x="22.81836" y="39" textLength="22.68164">be fi</tspan><tspan font-family="Helvetica" font-size="12" font-style="italic" font-weight="500" fill="#666" x="45.5" y="39" textLength="22.68164">xed.</tspan></text><path d="M 150.36395 317.63605 C 153.87869 321.15076 153.87869 326.84924 150.36395 330.36395 C 146.84924 333.87869 141.15076 333.87869 137.63605 330.36395 C 134.12131 326.84924 134.12131 321.15076 137.63605 317.63605 C 141.15076 314.12131 146.84924 314.12131 150.36395 317.63605" stroke="#999" stroke-linecap="round" stroke-linejoin="round" stroke-width="1" stroke-dasharray="4,4"/><path d="M 134.499996 324 L 127.499996 324 L 90 324 L 81 324 L 81 198" stroke="#999" stroke-linecap="round" stroke-linejoin="round" stroke-width="1" stroke-dasharray="4,4"/><rect x="72" y="522" width="342" height="36" fill="white"/><path d="M 414 558 L 72 558 L 72 522 L 414 522 Z" stroke="#999" stroke-linecap="round" stroke-linejoin="round" stroke-width="1" stroke-dasharray="4,4"/><text transform="translate(76 526)" fill="#666"><tspan font-family="Helvetica" font-size="12" font-style="italic" font-weight="500" fill="#666" x="7.241211" y="11" textLength="322.85156">The ticket has a patch which applies cleanly and includes all </tspan><tspan font-family="Helvetica" font-size="12" font-style="italic" font-weight="500" fill="#666" x="5.9052734" y="25" textLength="127.42383">needed tests and docs. </tspan><tspan font-family="Helvetica" font-size="12" font-style="italic" font-weight="500" fill="#666" x="132.67285" y="25" textLength="8.0039062">A</tspan><tspan font-family="Helvetica" font-size="12" font-style="italic" font-weight="500" fill="#666" x="140.02051" y="25" textLength="188.07422"> core developer can commit it as is.</tspan></text><path d="M 150.36395 407.63605 C 153.87869 411.15076 153.87869 416.84924 150.36395 420.36395 C 146.84924 423.8787 141.15076 423.8787 137.63605 420.36395 C 134.12131 416.84924 134.12131 411.15076 137.63605 407.63605 C 141.15076 404.1213 146.84924 404.1213 150.36395 407.63605" stroke="#999" stroke-linecap="round" stroke-linejoin="round" stroke-width="1" stroke-dasharray="4,4"/><path d="M 134.499996 414 L 127.499996 414 L 90 414 L 81 414 L 81 522" stroke="#999" stroke-linecap="round" stroke-linejoin="round" stroke-width="1" stroke-dasharray="4,4"/><line x1="252" y1="288" x2="303.79966" y2="317.5998" marker-end="url(#FilledArrow_Marker)" stroke="green" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/></g></g></svg> diff --git a/docs/internals/committers.txt b/docs/internals/committers.txt index 7900dd8cd0..a0649f38a2 100644 --- a/docs/internals/committers.txt +++ b/docs/internals/committers.txt @@ -14,8 +14,9 @@ Journal-World`_ of Lawrence, Kansas, USA. programming", and in technical circles as "the guy who invented Django." He was lead developer at World Online for 2.5 years, during which time - Django was developed and implemented on World Online's sites. He's now the - leader and founder of EveryBlock_, a "news feed for your block". + Django was developed and implemented on World Online's sites. He was the + leader and founder of EveryBlock_, a "news feed for your block." He now + develops for Soundslice_. Adrian lives in Chicago, USA. @@ -40,13 +41,15 @@ Journal-World`_ of Lawrence, Kansas, USA. `Wilson Miner`_ Wilson's design-fu is what makes Django look so nice. He designed the Web site you're looking at right now, as well as Django's acclaimed admin - interface. Wilson is the designer for EveryBlock_. + interface. Wilson was the designer for EveryBlock and Rdio_. He now + designs for Facebook. Wilson lives in San Francisco, USA. .. _lawrence journal-world: http://ljworld.com/ .. _adrian holovaty: http://holovaty.com/ .. _everyblock: http://everyblock.com/ +.. _soundslice: http://www.soundslice.com/ .. _simon willison: http://simonwillison.net/ .. _web-development blog: `simon willison`_ .. _jacob kaplan-moss: http://jacobian.org/ @@ -85,6 +88,8 @@ Malcolm Tredinnick When he's not busy being an International Man of Mystery, Malcolm lives in Sydney, Australia. + *Malcolm passed away on March 17, 2013.* + `Russell Keith-Magee`_ Russell studied physics as an undergraduate, and studied neural networks for his PhD. His first job was with a startup in the defense industry developing @@ -100,9 +105,9 @@ Malcolm Tredinnick .. _russell keith-magee: http://cecinestpasun.com/ Joseph Kocherhans - Joseph is currently a developer at EveryBlock_, and previously worked for - the Lawrence Journal-World where he built most of the backend for their - Marketplace site. He often disappears for several days into the woods, + Joseph was the director of lead development at EveryBlock and previously + developed at the Lawrence Journal-World. He is treasurer of the `Django + Software Foundation`_. He often disappears for several days into the woods, attempts to teach himself computational linguistics, and annoys his neighbors with his Charango_ playing. @@ -113,6 +118,7 @@ Joseph Kocherhans Joseph lives in Chicago, USA. +.. _django software foundation: https://www.djangoproject.com/foundation/ .. _charango: http://en.wikipedia.org/wiki/Charango `Luke Plant`_ @@ -419,6 +425,22 @@ Jeremy Dunck .. _Preston Holmes: http://www.ptone.com/ +`Simon Charette`_ + Simon is a mathematic student who discovered Django while searching for a + replacement framework to an in-house PHP entity. Since that faithful day + Django has been a big part of his life. So far, he's been involved in some + ORM and forms API fixes. + + Apart from contributing to multiple open source projects he spends most of + his spare-time playing `Ultimate Frisbee`_ and working part-time + at this awesome place called `Reptiletech`_. + + Simon lives in Montréal, Québec, Canada. + +.. _Simon Charette: https://github.com/charettes +.. _Ultimate Frisbee: http://www.montrealultimate.ca +.. _Reptiletech: http://www.reptiletech.com + Specialists ----------- diff --git a/docs/internals/contributing/committing-code.txt b/docs/internals/contributing/committing-code.txt index 67dda02f8b..bc2f97a485 100644 --- a/docs/internals/contributing/committing-code.txt +++ b/docs/internals/contributing/committing-code.txt @@ -116,7 +116,7 @@ Practicality beats purity, so it is up to each committer to decide how much history mangling to do for a pull request. The main points are engaging the community, getting work done, and having a usable commit history. -.. _committing-guidlines: +.. _committing-guidelines: Committing guidelines --------------------- diff --git a/docs/internals/contributing/new-contributors.txt b/docs/internals/contributing/new-contributors.txt index b752503248..0d4ad0cf3f 100644 --- a/docs/internals/contributing/new-contributors.txt +++ b/docs/internals/contributing/new-contributors.txt @@ -140,12 +140,3 @@ FAQ Short answer: No. It's always better to get another set of eyes on a ticket. If you're having trouble getting that second set of eyes, see question 1, above. - -3. **My ticket has been in DDN forever! What should I do?** - - Design Decision Needed requires consensus about the right solution. At the - very least it needs consensus among the core developers, and ideally it has - consensus from the community as well. The best way to accomplish this is to - start a thread on the django-developers mailing list, and for very complex - issues to start a wiki page summarizing the problem and the possible - solutions. diff --git a/docs/internals/contributing/triaging-tickets.txt b/docs/internals/contributing/triaging-tickets.txt index 84f70fd731..bc6148ca46 100644 --- a/docs/internals/contributing/triaging-tickets.txt +++ b/docs/internals/contributing/triaging-tickets.txt @@ -50,9 +50,9 @@ attribute easily tells us what and who each ticket is waiting on. Since a picture is worth a thousand words, let's start there: -.. image:: /internals/_images/djangotickets.png - :height: 451 - :width: 590 +.. image:: /internals/_images/triage_process.* + :height: 501 + :width: 400 :alt: Django's ticket triage workflow We've got two roles in this diagram: @@ -119,7 +119,14 @@ Beyond that there are several considerations: * **Accepted + No Flags** The ticket is valid, but no one has submitted a patch for it yet. Often this - means you could safely start writing a patch for it. + means you could safely start writing a patch for it. This is generally more + true for the case of accepted bugs than accepted features. A ticket for a bug + that has been accepted means that the issue has been verified by at least one + triager as a legitimate bug - and should probably be fixed if possible. An + accepted new feature may only mean that one triager thought the feature would + be good to have, but this alone does not represent a consensus view or imply + with any certainty that a patch will be accepted for that feature. Seek more + feedback before writing an extensive patch if you are in doubt. * **Accepted + Has Patch** @@ -128,30 +135,13 @@ Beyond that there are several considerations: and docs, running the test suite with the included patch, and leaving feedback on the ticket. -* **Accepted + Has Patch + (any other flag)** +* **Accepted + Has Patch + Needs ...** This means the ticket has been reviewed, and has been found to need further work. "Needs tests" and "Needs documentation" are self-explanatory. "Patch needs improvement" will generally be accompanied by a comment on the ticket explaining what is needed to improve the code. -Design Decision Needed -~~~~~~~~~~~~~~~~~~~~~~ - -This stage is for issues which may be contentious, may be backwards -incompatible, or otherwise involve high-level design decisions. These issues -should be discussed either in the ticket comments or on `django-developers`_. - -If a ticket has been marked as "DDN", decisions are generally eventually -made by the core committers, however that is not a requirement. See the -:ref:`New contributors' FAQ<new-contributors-faq>` for "My ticket has been in -DDN forever! What should I do?" - -This stage will often be used for feature requests. It can also be used for -issues that *might* be bugs, depending on opinion or interpretation. Obvious -bugs (such as crashes, incorrect query results, or non-compliance with a -standard) skip this stage and move straight to "Accepted". - Ready For Checkin ~~~~~~~~~~~~~~~~~ @@ -165,39 +155,54 @@ RFC forever! What should I do?" Someday/Maybe ~~~~~~~~~~~~~ -Generally only used for vague/high-level features or design ideas. These -tickets are uncommon and overall less useful since they don't describe +This stage isn't shown on the diagram. It's only used by core developers to +keep track of high-level ideas or long term feature requests. + +These tickets are uncommon and overall less useful since they don't describe concrete actionable issues. They are enhancement requests that we might consider adding someday to the framework if an excellent patch is submitted. -These tickets are not a high priority. +They are not a high priority. Other triage attributes ----------------------- A number of flags, appearing as checkboxes in Trac, can be set on a ticket: -* Has patch - This means the ticket has an associated - :doc:`patch<writing-code/submitting-patches>`. These will be reviewed - to see if the patch is "good". +Has patch +~~~~~~~~~ + +This means the ticket has an associated +:doc:`patch<writing-code/submitting-patches>`. These will be reviewed +to see if the patch is "good". + +Needs documentation +~~~~~~~~~~~~~~~~~~~ -* Needs documentation: - This flag is used for tickets with patches that need associated - documentation. Complete documentation of features is a prerequisite - before we can check them into the codebase. +This flag is used for tickets with patches that need associated +documentation. Complete documentation of features is a prerequisite +before we can check them into the codebase. -* Needs tests - This flags the patch as needing associated unit tests. Again, this - is a required part of a valid patch. +Needs tests +~~~~~~~~~~~ -* Patch needs improvement - This flag means that although the ticket *has* a patch, it's not quite - ready for checkin. This could mean the patch no longer applies - cleanly, there is a flaw in the implementation, or that the code - doesn't meet our standards. +This flags the patch as needing associated unit tests. Again, this +is a required part of a valid patch. -* Easy pickings - Tickets that would require small, easy, patches. +Patch needs improvement +~~~~~~~~~~~~~~~~~~~~~~~ + +This flag means that although the ticket *has* a patch, it's not quite +ready for checkin. This could mean the patch no longer applies +cleanly, there is a flaw in the implementation, or that the code +doesn't meet our standards. + +Easy pickings +~~~~~~~~~~~~~ + +Tickets that would require small, easy, patches. + +Type +~~~~ Tickets should be categorized by *type* between: @@ -211,19 +216,47 @@ Tickets should be categorized by *type* between: For when nothing is broken but something could be made cleaner, better, faster, stronger. -Tickets should also be classified into *components* indicating which area of +Component +~~~~~~~~~ + +Tickets should be classified into *components* indicating which area of the Django codebase they belong to. This makes tickets better organized and easier to find. +Severity +~~~~~~~~ + The *severity* attribute is used to identify blockers, that is, issues which should get fixed before releasing the next version of Django. Typically those issues are bugs causing regressions from earlier versions or potentially causing severe data losses. This attribute is quite rarely used and the vast majority of tickets have a severity of "Normal". -Finally, it is possible to use the *version* attribute to indicate in which +Version +~~~~~~~ + +It is possible to use the *version* attribute to indicate in which version the reported bug was identified. +UI/UX +~~~~~ + +This flag is used for tickets that relate to User Interface and User +Experiences questions. For example, this flag would be appropriate for +user-facing features in forms or the admin interface. + +Cc +~~ + +You may add your username or email address to this field to be notified when +new contributions are made to the ticket. + +Keywords +~~~~~~~~ + +With this field you may label a ticket with multiple keywords. This can be +useful, for example, to group several tickets of a same theme. + .. _closing-tickets: Closing Tickets @@ -301,20 +334,23 @@ developers and bring the issue to django-developers_ instead. How can I help with triaging? ----------------------------- -Although the core developers make the big decisions in the ticket triage -process, there's a lot that general community members can do to help the -triage process. Really, **ANYONE** can help. +The triage process is primarily driven by community members. Really, +**ANYONE** can help. + +Core developers may provide feedback on issues they're familiar with, or make +decisions on controversial ones, but they aren't responsible for triaging +tickets in general. -Start by `creating an account on Trac`_. If you have an account but have -forgotten your password, you can reset it using the `password reset page`_. +To get involved, start by `creating an account on Trac`_. If you have an +account but have forgotten your password, you can reset it using the `password +reset page`_. Then, you can help out by: * Closing "Unreviewed" tickets as "invalid", "worksforme" or "duplicate." -* Promoting "Unreviewed" tickets to "Design decision needed" if a design - decision needs to be made, or "Accepted" in case of obvious bugs or - sensible, clearly defined, feature requests. +* Closing "Unreviewed" tickets as "needsinfo" when they're feature requests + requiring a discussion on `django-developers`_. * Correcting the "Needs tests", "Needs documentation", or "Has patch" flags for tickets where they are incorrectly set. @@ -322,22 +358,18 @@ Then, you can help out by: * Setting the "`Easy pickings`_" flag for tickets that are small and relatively straightforward. +* Set the *type* of tickets that are still uncategorized. + * Checking that old tickets are still valid. If a ticket hasn't seen any activity in a long time, it's possible that the problem has been fixed but the ticket hasn't yet been closed. -* Contacting the owners of tickets that have been claimed but have not - seen any recent activity. If the owner doesn't respond after a week - or so, remove the owner's claim on the ticket. - * Identifying trends and themes in the tickets. If there a lot of bug reports about a particular part of Django, it may indicate we should consider refactoring that part of the code. If a trend is emerging, you should raise it for discussion (referencing the relevant tickets) on `django-developers`_. -* Set the *type* of tickets that are still uncategorized. - * Verify if patches submitted by other users are correct. If they do and also contain appropriate documentation and tests then move them to the "Ready for Checkin" stage. If they don't then leave a comment to explain diff --git a/docs/internals/contributing/writing-code/coding-style.txt b/docs/internals/contributing/writing-code/coding-style.txt index a699e39bd8..21146600b4 100644 --- a/docs/internals/contributing/writing-code/coding-style.txt +++ b/docs/internals/contributing/writing-code/coding-style.txt @@ -136,14 +136,17 @@ Model style * ``def get_absolute_url()`` * Any custom methods -* If ``choices`` is defined for a given model field, define the choices as - a tuple of tuples, with an all-uppercase name, either near the top of - the model module or just above the model class. Example:: +* If ``choices`` is defined for a given model field, define each choice as + a tuple of tuples, with an all-uppercase name as a class attribute on the + model. Example:: - DIRECTION_CHOICES = ( - ('U', 'Up'), - ('D', 'Down'), - ) + class MyModel(models.Model): + DIRECTION_UP = 'U' + DIRECTION_DOWN = 'D' + DIRECTION_CHOICES = ( + (DIRECTION_UP, 'Up'), + (DIRECTION_DOWN, 'Down'), + ) Use of ``django.conf.settings`` ------------------------------- @@ -177,9 +180,9 @@ That means that the ability for third parties to import the module at the top level is incompatible with the ability to configure the settings object manually, or makes it very difficult in some circumstances. -Instead of the above code, a level of laziness or indirection must be used, such -as :class:`django.utils.functional.LazyObject`, -:func:`django.utils.functional.lazy` or ``lambda``. +Instead of the above code, a level of laziness or indirection must be used, +such as ``django.utils.functional.LazyObject``, +``django.utils.functional.lazy()`` or ``lambda``. Miscellaneous ------------- diff --git a/docs/internals/contributing/writing-code/submitting-patches.txt b/docs/internals/contributing/writing-code/submitting-patches.txt index a90dc32605..ed8aad99b3 100644 --- a/docs/internals/contributing/writing-code/submitting-patches.txt +++ b/docs/internals/contributing/writing-code/submitting-patches.txt @@ -176,8 +176,10 @@ Compressing JavaScript ~~~~~~~~~~~~~~~~~~~~~~ To simplify the process of providing optimized javascript code, Django -includes a handy script which should be used to create a "minified" version. -This script is located at ``django/contrib/admin/static/admin/js/compress.py``. +includes a handy python script which should be used to create a "minified" +version. To run it:: + + python django/contrib/admin/bin/compress.py Behind the scenes, ``compress.py`` is a front-end for Google's `Closure Compiler`_ which is written in Java. However, the Closure Compiler diff --git a/docs/internals/contributing/writing-code/unit-tests.txt b/docs/internals/contributing/writing-code/unit-tests.txt index 4e702ff83e..f56bf1cdeb 100644 --- a/docs/internals/contributing/writing-code/unit-tests.txt +++ b/docs/internals/contributing/writing-code/unit-tests.txt @@ -7,16 +7,14 @@ code base. It's our policy to make sure all tests pass at all times. The tests cover: -* Models and the database API (``tests/modeltests``), -* Everything else in core Django code (``tests/regressiontests``), -* :ref:`contrib-apps` (``django/contrib/<app>/tests`` or - ``tests/regressiontests/<app>_...``). +* Models, the database API and everything else in core Django core (``tests/``), +* :ref:`contrib-apps` (``django/contrib/<app>/tests`` or ``tests/<app>_...``). We appreciate any and all contributions to the test suite! The Django tests all use the testing infrastructure that ships with Django for -testing applications. See :doc:`Testing Django applications </topics/testing>` -for an explanation of how to write new tests. +testing applications. See :doc:`Testing Django applications +</topics/testing/overview>` for an explanation of how to write new tests. .. _running-unit-tests: @@ -105,9 +103,9 @@ internationalization, type: ./runtests.py --settings=path.to.settings generic_relations i18n -How do you find out the names of individual tests? Look in -``tests/modeltests`` and ``tests/regressiontests`` — each directory name -there is the name of a test. Contrib app names are also valid test names. +How do you find out the names of individual tests? Look in ``tests/`` — each +directory name there is the name of a test. Contrib app names are also valid +test names. If you just want to run a particular class of tests, you can specify a list of paths to individual test classes. For example, to run the ``TranslationTests`` @@ -128,13 +126,13 @@ Running the Selenium tests Some admin tests require Selenium 2, Firefox and Python >= 2.6 to work via a real Web browser. To allow those tests to run and not be skipped, you must -install the selenium_ package (version > 2.13) into your Python path. - -Then, run the tests normally, for example: +install the selenium_ package (version > 2.13) into your Python path and run +the tests with the ``--selenium`` option: .. code-block:: bash - ./runtests.py --settings=test_sqlite admin_inlines + ./runtests.py --settings=test_sqlite --selenium admin_inlines + .. _running-unit-tests-dependencies: @@ -145,9 +143,6 @@ If you want to run the full suite of tests, you'll need to install a number of dependencies: * PyYAML_ -* Markdown_ -* Textile_ -* Docutils_ * setuptools_ * memcached_, plus a :ref:`supported Python binding <memcached>` * gettext_ (:ref:`gettext_on_windows`) @@ -160,9 +155,6 @@ Each of these dependencies is optional. If you're missing any of them, the associated tests will be skipped. .. _PyYAML: http://pyyaml.org/wiki/PyYAML -.. _Markdown: http://pypi.python.org/pypi/Markdown/1.7 -.. _Textile: http://pypi.python.org/pypi/textile -.. _docutils: http://pypi.python.org/pypi/docutils/0.4 .. _setuptools: http://pypi.python.org/pypi/setuptools/ .. _memcached: http://memcached.org/ .. _gettext: http://www.gnu.org/software/gettext/manual/gettext.html @@ -200,7 +192,7 @@ multiple modules by using a ``tests`` directory in the normal Python way. For the tests to be found, a ``models.py`` file must exist, even if it's empty. If you have URLs that need to be mapped, put them in ``tests/urls.py``. -To run tests for just one contrib app (e.g. ``markup``), use the same +To run tests for just one contrib app (e.g. ``auth``), use the same method as above:: - ./runtests.py --settings=settings markup + ./runtests.py --settings=settings auth diff --git a/docs/internals/contributing/writing-code/working-with-git.txt b/docs/internals/contributing/writing-code/working-with-git.txt index d4a95ae45a..dcfdd9e85b 100644 --- a/docs/internals/contributing/writing-code/working-with-git.txt +++ b/docs/internals/contributing/writing-code/working-with-git.txt @@ -81,7 +81,7 @@ commit them:: git commit When writing the commit message, follow the :ref:`commit message -guidelines <committing-guidlines>` to ease the work of the committer. If +guidelines <committing-guidelines>` to ease the work of the committer. If you're uncomfortable with English, try at least to describe precisely what the commit does. @@ -121,7 +121,7 @@ a pull request at GitHub. A good pull request means: * well-formed messages for each commit: a summary line and then paragraphs wrapped at 72 characters thereafter -- see the :ref:`committing guidelines - <committing-guidlines>` for more details, + <committing-guidelines>` for more details, * documentation and tests, if needed -- actually tests are always needed, except for documentation changes. diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index 414da30ff8..1533e25dc8 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -14,13 +14,13 @@ See the :doc:`Django 1.2 release notes</releases/1.2>` for more details on these changes. * ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` will be removed. Use - the {% csrf_token %} template tag inside forms to enable CSRF + the ``{% csrf_token %}`` template tag inside forms to enable CSRF protection. ``CsrfViewMiddleware`` remains and is enabled by default. * The old imports for CSRF functionality (``django.contrib.csrf.*``), which moved to core in 1.2, will be removed. -* The :mod:`django.contrib.gis.db.backend` module will be removed in favor +* The ``django.contrib.gis.db.backend`` module will be removed in favor of the specific backends. * ``SMTPConnection`` will be removed in favor of a generic Email backend API. @@ -111,7 +111,7 @@ See the :doc:`Django 1.3 release notes</releases/1.3>` for more details on these changes. * Starting Django without a :setting:`SECRET_KEY` will result in an exception - rather than a `DeprecationWarning`. (This is accelerated from the usual + rather than a ``DeprecationWarning``. (This is accelerated from the usual deprecation path; see the :doc:`Django 1.4 release notes</releases/1.4>`.) * The ``mod_python`` request handler will be removed. The ``mod_wsgi`` @@ -122,23 +122,23 @@ these changes. The :attr:`~django.test.client.Response.templates` attribute should be used instead. -* The :class:`~django.test.simple.DjangoTestRunner` will be removed. +* The ``django.test.simple.DjangoTestRunner`` will be removed. Instead use a unittest-native class. The features of the - :class:`django.test.simple.DjangoTestRunner` (including fail-fast and + ``django.test.simple.DjangoTestRunner`` (including fail-fast and Ctrl-C test termination) can currently be provided by the unittest-native - :class:`TextTestRunner`. + :class:`~unittest.TextTestRunner`. * The undocumented function - :func:`django.contrib.formtools.utils.security_hash` will be removed, - instead use :func:`django.contrib.formtools.utils.form_hmac` + ``django.contrib.formtools.utils.security_hash`` will be removed, + instead use ``django.contrib.formtools.utils.form_hmac`` * The function-based generic view modules will be removed in favor of their class-based equivalents, outlined :doc:`here </topics/class-based-views/index>`. -* The :class:`~django.core.servers.basehttp.AdminMediaHandler` will be +* The ``django.core.servers.basehttp.AdminMediaHandler`` will be removed. In its place use - :class:`~django.contrib.staticfiles.handlers.StaticFilesHandler`. + ``django.contrib.staticfiles.handlers.StaticFilesHandler``. * The template tags library ``adminmedia`` and the template tag ``{% admin_media_prefix %}`` will be removed in favor of the generic static files @@ -150,8 +150,7 @@ these changes. an implied string. In 1.4, this behavior is provided by a version of the tag in the ``future`` template tag library. -* The :djadmin:`reset` and :djadmin:`sqlreset` management commands - will be removed. +* The ``reset`` and ``sqlreset`` management commands will be removed. * Authentication backends will need to support an inactive user being passed to all methods dealing with permissions. @@ -162,15 +161,14 @@ these changes. a :class:`~django.contrib.gis.geos.GEOSException` when called on a geometry with no SRID value. -* :class:`~django.http.CompatCookie` will be removed in favor of - :class:`~django.http.SimpleCookie`. +* ``django.http.CompatCookie`` will be removed in favor of + ``django.http.SimpleCookie``. -* :class:`django.core.context_processors.PermWrapper` and - :class:`django.core.context_processors.PermLookupDict` will be removed in +* ``django.core.context_processors.PermWrapper`` and + ``django.core.context_processors.PermLookupDict`` will be removed in favor of the corresponding - :class:`django.contrib.auth.context_processors.PermWrapper` and - :class:`django.contrib.auth.context_processors.PermLookupDict`, - respectively. + ``django.contrib.auth.context_processors.PermWrapper`` and + ``django.contrib.auth.context_processors.PermLookupDict``, respectively. * The :setting:`MEDIA_URL` or :setting:`STATIC_URL` settings will be required to end with a trailing slash to ensure there is a consistent @@ -200,30 +198,37 @@ these changes. See the :doc:`Django 1.4 release notes</releases/1.4>` for more details on these changes. +* ``django.contrib.databrowse`` will be removed. + +* ``django.contrib.localflavor`` will be removed following an accelerated + deprecation. + +* ``django.contrib.markup`` will be removed following an accelerated + deprecation. + * The compatibility modules ``django.utils.copycompat`` and ``django.utils.hashcompat`` as well as the functions ``django.utils.itercompat.all`` and ``django.utils.itercompat.any`` will be removed. The Python builtin versions should be used instead. -* The :func:`~django.views.decorators.csrf.csrf_response_exempt` and - :func:`~django.views.decorators.csrf.csrf_view_exempt` decorators will +* The ``csrf_response_exempt`` and ``csrf_view_exempt`` decorators will be removed. Since 1.4 ``csrf_response_exempt`` has been a no-op (it returns the same function), and ``csrf_view_exempt`` has been a synonym for ``django.views.decorators.csrf.csrf_exempt``, which should be used to replace it. -* The :class:`~django.core.cache.backends.memcached.CacheClass` backend +* The ``django.core.cache.backends.memcached.CacheClass`` backend was split into two in Django 1.3 in order to introduce support for - PyLibMC. The historical :class:`~django.core.cache.backends.memcached.CacheClass` - will be removed in favor of :class:`~django.core.cache.backends.memcached.MemcachedCache`. + PyLibMC. The historical ``CacheClass`` will be removed in favor of + ``django.core.cache.backends.memcached.MemcachedCache``. * The UK-prefixed objects of ``django.contrib.localflavor.uk`` will only be accessible through their GB-prefixed names (GB is the correct ISO 3166 code for United Kingdom). -* The :setting:`IGNORABLE_404_STARTS` and :setting:`IGNORABLE_404_ENDS` - settings have been superseded by :setting:`IGNORABLE_404_URLS` in - the 1.4 release. They will be removed. +* The ``IGNORABLE_404_STARTS`` and ``IGNORABLE_404_ENDS`` settings have been + superseded by :setting:`IGNORABLE_404_URLS` in the 1.4 release. They will be + removed. * The :doc:`form wizard </ref/contrib/formtools/form-wizard>` has been refactored to use class-based views with pluggable backends in 1.4. @@ -237,8 +242,8 @@ these changes. :setting:`LOGGING` setting should include this filter explicitly if it is desired. -* The builtin truncation functions :func:`django.utils.text.truncate_words` - and :func:`django.utils.text.truncate_html_words` will be removed in +* The builtin truncation functions ``django.utils.text.truncate_words()`` + and ``django.utils.text.truncate_html_words()`` will be removed in favor of the ``django.utils.text.Truncator`` class. * The :class:`~django.contrib.gis.geoip.GeoIP` class was moved to @@ -251,11 +256,8 @@ these changes. :data:`~django.conf.urls.handler500`, are now available through :mod:`django.conf.urls` . -* The Databrowse contrib module will be removed. - -* The functions :func:`~django.core.management.setup_environ` and - :func:`~django.core.management.execute_manager` will be removed from - :mod:`django.core.management`. This also means that the old (pre-1.4) +* The functions ``setup_environ()`` and ``execute_manager()`` will be removed + from :mod:`django.core.management`. This also means that the old (pre-1.4) style of :file:`manage.py` file will no longer work. * Setting the ``is_safe`` and ``needs_autoescape`` flags as attributes of @@ -265,8 +267,11 @@ these changes. in 1.4. The backward compatibility will be removed -- ``HttpRequest.raw_post_data`` will no longer work. -* ``django.contrib.markup`` will be removed following an accelerated - deprecation. +* The value for the ``post_url_continue`` parameter in + ``ModelAdmin.response_add()`` will have to be either ``None`` (to redirect + to the newly created object's edit page) or a pre-formatted url. String + formats, such as the previous default ``'../%s/'``, will not be accepted any + more. 1.7 --- @@ -284,8 +289,14 @@ these changes. specified as a plain string instead of a tuple will be removed and raise an exception. -* The ``mimetype`` argument to :class:`~django.http.HttpResponse` ``__init__`` - will be removed (``content_type`` should be used instead). +* The ``mimetype`` argument to the ``__init__`` methods of + :class:`~django.http.HttpResponse`, + :class:`~django.template.response.SimpleTemplateResponse`, and + :class:`~django.template.response.TemplateResponse`, will be removed. + ``content_type`` should be used instead. This also applies to the + :func:`~django.shortcuts.render_to_response` shortcut and + the sitemamp views, :func:`~django.contrib.sitemaps.views.index` and + :func:`~django.contrib.sitemaps.views.sitemap`. * When :class:`~django.http.HttpResponse` is instantiated with an iterator, or when :attr:`~django.http.HttpResponse.content` is set to an iterator, @@ -302,6 +313,68 @@ these changes. * The ``depth`` keyword argument will be removed from :meth:`~django.db.models.query.QuerySet.select_related`. +* The undocumented ``get_warnings_state()``/``restore_warnings_state()`` + functions from :mod:`django.test.utils` and the ``save_warnings_state()``/ + ``restore_warnings_state()`` + :ref:`django.test.*TestCase <django-testcase-subclasses>` methods are + deprecated. Use the :class:`warnings.catch_warnings` context manager + available starting with Python 2.6 instead. + +* The undocumented ``check_for_test_cookie`` method in + :class:`~django.contrib.auth.forms.AuthenticationForm` will be removed + following an accelerated deprecation. Users subclassing this form should + remove calls to this method, and instead ensure that their auth related views + are CSRF protected, which ensures that cookies are enabled. + +1.8 +--- + +* ``django.contrib.comments`` will be removed. + +* The following transaction management APIs will be removed: + + - ``TransactionMiddleware``, + - the decorators and context managers ``autocommit``, ``commit_on_success``, + and ``commit_manually``, defined in ``django.db.transaction``, + - the functions ``commit_unless_managed`` and ``rollback_unless_managed``, + also defined in ``django.db.transaction``, + - the ``TRANSACTIONS_MANAGED`` setting. + + Upgrade paths are described in the :ref:`transaction management docs + <transactions-upgrading-from-1.5>`. + +* The :ttag:`cycle` and :ttag:`firstof` template tags will auto-escape their + arguments. In 1.6 and 1.7, this behavior is provided by the version of these + tags in the ``future`` template tag library. + +* The ``SEND_BROKEN_LINK_EMAILS`` setting will be removed. Add the + :class:`django.middleware.common.BrokenLinkEmailsMiddleware` middleware to + your :setting:`MIDDLEWARE_CLASSES` setting instead. + +* ``Model._meta.module_name`` was renamed to ``model_name``. + +* Remove the backward compatible shims introduced to rename ``get_query_set`` + and similar queryset methods. This affects the following classes: + ``BaseModelAdmin``, ``ChangeList``, ``BaseCommentNode``, + ``GenericForeignKey``, ``Manager``, ``SingleRelatedObjectDescriptor`` and + ``ReverseSingleRelatedObjectDescriptor``. + +* Remove the backward compatible shims introduced to rename the attributes + ``ChangeList.root_query_set`` and ``ChangeList.query_set``. + +* ``django.conf.urls.shortcut`` and ``django.views.defaults.shortcut`` will be + removed. + +* The following private APIs will be removed: + + - ``django.db.close_connection()`` + - ``django.db.backends.creation.BaseDatabaseCreation.set_autocommit()`` + - ``django.db.transaction.is_managed()`` + - ``django.db.transaction.managed()`` + +* ``django.forms.widgets.RadioInput`` will be removed in favor of + ``django.forms.widgets.RadioChoiceInput``. + 2.0 --- diff --git a/docs/internals/git.txt b/docs/internals/git.txt index 948f9a1f7e..2b1a279d89 100644 --- a/docs/internals/git.txt +++ b/docs/internals/git.txt @@ -134,7 +134,7 @@ part of Django itself, and so are no longer separately maintained: of Django since the 0.95 release. * ``multi-auth``: A refactoring of :doc:`Django's bundled - authentication framework </topics/auth>` which added support for + authentication framework </topics/auth/index>` which added support for :ref:`authentication backends <authentication-backends>`. This has been part of Django since the 0.95 release. diff --git a/docs/internals/howto-release-django.txt b/docs/internals/howto-release-django.txt new file mode 100644 index 0000000000..a49251da76 --- /dev/null +++ b/docs/internals/howto-release-django.txt @@ -0,0 +1,320 @@ +===================== +How is Django Formed? +===================== + +This document explains how to release Django. If you're unlucky enough to +be driving a release, you should follow these instructions to get the +package out. + +**Please, keep these instructions up-to-date if you make changes!** The point +here is to be descriptive, not proscriptive, so feel free to streamline or +otherwise make changes, but **update this document accordingly!** + +Overview +======== + +There are three types of releases that you might need to make + +* Security releases, disclosing and fixing a vulnerability. This'll + generally involve two or three simultaneous releases -- e.g. + 1.5.x, 1.6.x, and, depending on timing, perhaps a 1.7 alpha/beta/rc. + +* Regular version releases, either a final release (e.g. 1.5) or a + bugfix update (e.g. 1.5.1). + +* Pre-releases, e.g. 1.6 beta or something. + +In general the steps are about the same regardless, but there are a few +differences noted. The short version is: + +#. If this is a security release, pre-notify the security distribution list + at least one week before the actual release. + +#. Proofread (and create if needed) the release notes, looking for + organization, writing errors, deprecation timelines, etc. Draft a blog post + and email announcement. + +#. Update version numbers and create the release package(s)! + +#. Upload the package(s) to the ``djangoproject.com`` server. + +#. Unless this is a pre-release, add the new version(s) to PyPI. + +#. Declare the new version in the admin on ``djangoproject.com``. + +#. Post the blog entry and send out the email announcements. + +#. Update version numbers post-release. + +There are a lot of details, so please read on. + +Prerequisites +============= + +You'll need a few things hooked up to make this work: + +* A GPG key recorded as an acceptable releaser in the `Django releasers`__ + document. (If this key is not your default signing key, you'll need to add + ``-u you@example.com`` to every GPG signing command below, where + ``you@example.com`` is the email address associated with the key you want to + use.) + +* Access to Django's record on PyPI. + +* Access to the ``djangoproject.com`` server to upload files and trigger a + deploy. + +* Access to the admin on ``djangoproject.com`` as a "Site maintainer". + +* Access to post to ``django-announce``. + +* If this is a security release, access to the pre-notification distribution + list. + +If this is your first release, you'll need to coordinate with James and/or +Jacob to get all these things lined up. + +__ https://www.djangoproject.com/m/pgp/django-releasers.txt + +Pre-release tasks +================= + +A few items need to be taken care of before even beginning the release process. +This stuff starts about a week before the release; most of it can be done +any time leading up to the actual release: + +#. If this is a security release, send out pre-notification **one week** + before the release. We maintain a list of who gets these pre-notification + emails at *FIXME WHERE?*. This email should be signed by the key you'll use + for the release, and should include patches for each issue being fixed. + +#. As the release approaches, watch Trac to make sure no release blockers + are left for the upcoming release. + +#. Check with the other committers to make sure they don't have any + un-committed changes for the release. + +#. Proofread the release notes, including looking at the online + version to catch any broken links or reST errors, and make sure the + release notes contain the correct date. + +#. Double-check that the release notes mention deprecation timelines + for any APIs noted as deprecated, and that they mention any changes + in Python version support. + +#. Double-check that the release notes index has a link to the notes + for the new release; this will be in ``docs/releases/index.txt``. + +Preparing for release +===================== + +Write the announcement blog post for the release. You can enter it into the +admin at any time and mark it as inactive. Here are a few examples: `example +security release announcement`__, `example regular release announcement`__, +`example pre-release announcement`__. + +__ https://www.djangoproject.com/weblog/2013/feb/19/security/ +__ https://www.djangoproject.com/weblog/2012/mar/23/14/ +__ https://www.djangoproject.com/weblog/2012/nov/27/15-beta-1/ + +Actually rolling the release +============================ + +OK, this is the fun part, where we actually push out a release! + +#. Check `Jenkins`__ is green for the version(s) you're putting out. You + probably shouldn't issue a release until it's green. + + __ http://ci.djangoproject.com + +#. A release always begins from a release branch, so you should make sure + you're on a stable branch and up-to-date. For example:: + + git checkout stable/1.5.x + git pull + +#. If this is a security release, merge the appropriate patches from + ``django-private``. Rebase these patches as necessary to make each one a + simple commit on the release branch rather than a merge commit. To ensure + this, merge them with the ``--ff-only`` flag; for example:: + + git checkout stable/1.5.x + git merge --ff-only security/1.5.x + + (This assumes ``security/1.5.x`` is a branch in the ``django-private`` repo + containing the necessary security patches for the next release in the 1.5 + series.) + + If git refuses to merge with ``--ff-only``, switch to the security-patch + branch and rebase it on the branch you are about to merge it into (``git + checkout security/1.5.x; git rebase stable/1.5.x``) and then switch back and + do the merge. Make sure the commit message for each security fix explains + that the commit is a security fix and that an announcement will follow + (`example security commit`__) + + __ https://github.com/django/django/commit/3ef4bbf495cc6c061789132e3d50a8231a89406b + +#. Update version numbers for the release. This has to happen in three + places: ``django/__init__.py``, ``docs/conf.py``, and ``setup.py``. + Please see `notes on setting the VERSION tuple`_ below for details + on ``VERSION``. Here's `an example commit updating version numbers`__ + + __ https://github.com/django/django/commit/18d920ea4839fb54f9d2a5dcb555b6a5666ee469 + +#. If this is a pre-release package, update the "Development Status" trove + classifier in ``setup.py`` to reflect this. Otherwise, make sure the + classifier is set to ``Development Status :: 5 - Production/Stable``. + +#. Tag the release using ``git tag``. For example:: + + git tag --sign --message="Django 1.5.1" 1.5.1 + + You can check your work by running ``git tag --verify <tag>``. + +#. Push your work, including the tag: ``git push --tags``. + +#. Make sure you have an absolutely clean tree by running ``git clean -dfx``. + +#. Run ``python setup.py sdist`` to generate the release package. This will + create the release package in a ``dist/`` directory. + +#. Generate the hashes of the release package:: + + $ md5sum dist/Django-<version>.tar.gz + $ sha1sum dist/Django-<version>.tar.gz + + *FIXME: perhaps we should switch to sha256?* + +#. Create a "checksums" file containing the hashes and release information. + You can start with `a previous checksums file`__ and replace the + dates, keys, links, and checksums. *FIXME: make a template file.* + + __ https://www.djangoproject.com/m/pgp/Django-1.5b1.checksum.txt + +#. Sign the checksum file (``gpg --clearsign + Django-<version>.checksum.txt``). This generates a signed document, + ``Django-<version>.checksum.txt.asc`` which you can then verify using ``gpg + --verify Django-<version>.checksum.txt.asc``. + +If you're issuing multiple releases, repeat these steps for each release. + +Making the release(s) available to the public +============================================= + +Now you're ready to actually put the release out there. To do this: + +#. Upload the release package(s) to the djangoproject server; releases go + in ``/home/www/djangoproject.com/src/media/releases``, under a + directory for the appropriate version number (e.g. + ``/home/www/djangoproject.com/src/media/releases/1.5`` for a ``1.5.x`` + release.). + +#. Upload the checksum file(s); these go in + ``/home/www/djangoproject.com/src/media/pgp``. + +#. Test that the release packages install correctly using ``easy_install`` + and ``pip``. Here's one method (which requires `virtualenvwrapper`__):: + + $ mktmpenv + $ easy_install https://www.djangoproject.com/m/releases/1.5/Django-1.5.1.tar.gz + $ deactivate + $ mktmpenv + $ pip install https://www.djangoproject.com/m/releases/1.5/Django-1.5.1.tar.gz + $ deactivate + + This just tests that the tarballs are available (i.e. redirects are up) and + that they install correctly, but it'll catch silly mistakes. + + __ https://pypi.python.org/pypi/virtualenvwrapper + +#. Ask a few people on IRC to verify the checksums by visiting the checksums + file (e.g. https://www.djangoproject.com/m/pgp/Django-1.5b1.checksum.txt) + and following the instructions in it. For bonus points, they can also unpack + the downloaded release tarball and verify that its contents appear to be + correct (proper version numbers, no stray ``.pyc`` or other undesirable + files). + +#. If this is a release that should land on PyPI (i.e. anything except for + a pre-release), register the new package with PyPI by running + ``python setup.py register``. + +#. Upload the sdist you generated a few steps back through the PyPI web + interface. You'll log into PyPI, click "Django" in the right sidebar, + find the release you just registered, and click "files" to upload the + sdist. + + .. note:: + + Why can't we just use ``setup.py sdist upload``? Well, if we do it above + that pushes the sdist to PyPI before we've had a chance to sign, review + and test it. And we can't just ``setup.py upload`` without ``sdist`` + because ``setup.py`` prevents that. Nor can we ``sdist upload`` because + that would generate a *new* sdist that might not match the file we just + signed. Finally, uploading through the web interface is somewhat more + secure: it sends the file over HTTPS. + +#. Go to the `Add release page in the admin`__, enter the new release number + exactly as it appears in the name of the tarball (Django-<version>.tar.gz). + So for example enter "1.5.1" or "1.4-rc-2", etc. + + __ https://www.djangoproject.com/admin/releases/release/add/ + +#. Make the blog post announcing the release live. + +#. For a new version release (e.g. 1.5, 1.6), update the default stable version + of the docs by flipping the ``is_default`` flag to ``True`` on the + appropriate ``DocumentRelease`` object in the ``docs.djangoproject.com`` + database (this will automatically flip it to ``False`` for all + others). *FIXME: I had to do this via fab managepy:shell,docs but we should + probably make it possible to do via the admin.* + +#. Post the release announcement to the django-announce, + django-developers and django-users mailing lists. This should + include links to the announcement blog post and the release notes. + +Post-release +============ + +You're almost done! All that's left to do now is: + +#. Update the ``VERSION`` tuple in ``django/__init__.py`` again, + incrementing to whatever the next expected release will be. For + example, after releasing 1.5.1, update ``VERSION`` to + ``VERSION = (1, 5, 2, 'alpha', 0)``. + +#. For the first alpha release of a new version (when we create the + ``stable/1.?.x`` git branch), you'll want to create a new + ``DocumentRelease`` object in the ``docs.djangoproject.com`` database for + the new version's docs, and update the ``docs/fixtures/doc_releases.json`` + JSON fixture. *FIXME: what is the purpose of maintaining this fixture?* + +#. Add the release in `Trac's versions list`_ if necessary. Not all versions + are declared; take example on previous releases. + +.. _Trac's versions list: https://code.djangoproject.com/admin/ticket/versions + +Notes on setting the VERSION tuple +================================== + +Django's version reporting is controlled by the ``VERSION`` tuple in +``django/__init__.py``. This is a five-element tuple, whose elements +are: + +#. Major version. +#. Minor version. +#. Micro version. +#. Status -- can be one of "alpha", "beta", "rc" or "final". +#. Series number, for alpha/beta/RC packages which run in sequence + (allowing, for example, "beta 1", "beta 2", etc.). + +For a final release, the status is always "final" and the series +number is always 0. A series number of 0 with an "alpha" status will +be reported as "pre-alpha". + +Some examples: + +* ``(1, 2, 1, 'final', 0)`` --> "1.2.1" + +* ``(1, 3, 0, 'alpha', 0)`` --> "1.3 pre-alpha" + +* ``(1, 3, 0, 'beta', 2)`` --> "1.3 beta 2" diff --git a/docs/internals/index.txt b/docs/internals/index.txt index 3ff4eb62d0..9a80a90286 100644 --- a/docs/internals/index.txt +++ b/docs/internals/index.txt @@ -22,3 +22,4 @@ the hood". release-process deprecation git + howto-release-django diff --git a/docs/internals/release-process.txt b/docs/internals/release-process.txt index 8affddb5e0..29ce3914b4 100644 --- a/docs/internals/release-process.txt +++ b/docs/internals/release-process.txt @@ -13,12 +13,12 @@ Since version 1.0, Django's release numbering works as follows: * ``A`` is the *major version* number, which is only incremented for major changes to Django, and these changes are not necessarily - backwards-compatible. That is, code you wrote for Django 1.2 may break + backwards-compatible. That is, code you wrote for Django 1.6 may break when we release Django 2.0. * ``B`` is the *minor version* number, which is incremented for large yet - backwards compatible changes. Code written for Django 1.2 will continue - to work under Django 1.3. Exceptions to this rule will be listed in the + backwards compatible changes. Code written for Django 1.6 will continue + to work under Django 1.7. Exceptions to this rule will be listed in the release notes. * ``C`` is the *micro version* number, which is incremented for bug and @@ -27,67 +27,62 @@ Since version 1.0, Django's release numbering works as follows: can't be fixed without breaking backwards-compatibility. If this happens, the release notes will provide detailed upgrade instructions. -* In some cases, we'll make alpha, beta, or release candidate releases. - These are of the form ``A.B alpha/beta/rc N``, which means the ``Nth`` - alpha/beta/release candidate of version ``A.B``. +* Before a new minor release, we'll make alpha, beta, and release candidate + releases. These are of the form ``A.B alpha/beta/rc N``, which means the + ``Nth`` alpha/beta/release candidate of version ``A.B``. -In git, each Django release will have a tag indicating its version -number, signed with the Django release key. Additionally, each release -series (X.Y) has its own branch, and bugfix/security releases will be +In git, each Django release will have a tag indicating its version number, +signed with the Django release key. Additionally, each release series has its +own branch, called ``stable/A.B.x``, and bugfix/security releases will be issued from those branches. -For more information about how the Django project issues new releases -for security purposes, please see :doc:`our security policies -<security>`. +For more information about how the Django project issues new releases for +security purposes, please see :doc:`our security policies <security>`. Major releases -------------- Major releases (1.0, 2.0, etc.) will happen very infrequently (think "years", -not "months"), and will probably represent major, sweeping changes to Django. +not "months"), and may represent major, sweeping changes to Django. Minor releases -------------- -Minor release (1.1, 1.2, etc.) will happen roughly every nine months -- see -`release process`_, below for details. +Minor release (1.5, 1.6, etc.) will happen roughly every nine months -- see +`release process`_, below for details. These releases will contain new +features, improvements to existing features, and such. .. _internal-release-deprecation-policy: -These releases will contain new features, improvements to existing features, and -such. A minor release may deprecate certain features from previous releases. If a -feature in version ``A.B`` is deprecated, it will continue to work in version -``A.B+1``. In version ``A.B+2``, use of the feature will raise a -``DeprecationWarning`` but will continue to work. Version ``A.B+3`` will -remove the feature entirely. +A minor release may deprecate certain features from previous releases. If a +feature is deprecated in version ``A.B``, it will continue to work in versions +``A.B`` and ``A.B+1`` but raise warnings. It will be removed in version +``A.B+2``. -So, for example, if we decided to remove a function that existed in Django 1.0: +So, for example, if we decided to start the deprecation of a function in +Django 1.5: -* Django 1.1 will contain a backwards-compatible replica of the function - which will raise a ``PendingDeprecationWarning``. This warning is silent - by default; you need to explicitly turn on display of these warnings. +* Django 1.5 will contain a backwards-compatible replica of the function which + will raise a ``PendingDeprecationWarning``. This warning is silent by + default; you can turn on display of these warnings with the ``-Wd`` option + of Python. -* Django 1.2 will contain the backwards-compatible replica, but the warning +* Django 1.6 will contain the backwards-compatible replica, but the warning will be promoted to a full-fledged ``DeprecationWarning``. This warning is *loud* by default, and will likely be quite annoying. -* Django 1.3 will remove the feature outright. +* Django 1.7 will remove the feature outright. Micro releases -------------- -Micro releases (1.0.1, 1.0.2, 1.1.1, etc.) will be issued at least once half-way -between minor releases, and probably more often as needed. +Micro releases (1.5.1, 1.6.2, 1.6.1, etc.) will be issued as needed, often to +fix security issues. These releases will be 100% compatible with the associated minor release, unless this is impossible for security reasons. So the answer to "should I upgrade to the latest micro release?" will always be "yes." -Each minor release of Django will have a "release maintainer" appointed. This -person will be responsible for making sure that bug fixes are applied to both -trunk and the maintained micro-release branch. This person will also work with -the release manager to decide when to release the micro releases. - .. _backwards-compatibility-policy: Supported versions @@ -96,10 +91,10 @@ Supported versions At any moment in time, Django's developer team will support a set of releases to varying levels: -* The current development trunk will get new features and bug fixes +* The current development master will get new features and bug fixes requiring major refactoring. -* Patches applied to the trunk will also be applied to the last minor +* Patches applied to the master branch must also be applied to the last minor release, to be released as the next micro release, when they fix critical problems: @@ -111,40 +106,42 @@ varying levels: * Major functionality bugs in newly-introduced features. - The rule of thumb is that fixes will be backported to the last minor - release for bugs that would have prevented a release in the first place. + The rule of thumb is that fixes will be backported to the last minor release + for bugs that would have prevented a release in the first place (release + blockers). -* Security fixes will be applied to the current trunk and the previous two +* Security fixes will be applied to the current master and the previous two minor releases. +* Committers may choose to backport bugfixes at their own discretion, + provided they do not introduce backwards incompatibilities. + * Documentation fixes generally will be more freely backported to the last - release branch, at the discretion of the committer, and they don't need to - meet the "critical fixes only" bar. That's because it's highly advantageous - to have the docs for the last release be up-to-date and correct, and the - downside of backporting (risk of introducing regressions) is much less of a - concern. + release branch. That's because it's highly advantageous to have the docs for + the last release be up-to-date and correct, and the risk of introducing + regressions is much less of a concern. As a concrete example, consider a moment in time halfway between the release of -Django 1.3 and 1.4. At this point in time: +Django 1.6 and 1.7. At this point in time: -* Features will be added to development trunk, to be released as Django 1.4. +* Features will be added to development master, to be released as Django 1.7. -* Critical bug fixes will be applied to a ``1.3.X`` branch, and released as - 1.3.1, 1.3.2, etc. +* Critical bug fixes will be applied to the ``stable/1.6.X`` branch, and + released as 1.6.1, 1.6.2, etc. -* Security fixes will be applied to trunk, a ``1.3.X`` branch and a - ``1.2.X`` branch. They will trigger the release of ``1.3.1``, ``1.2.1``, - etc. +* Security fixes will be applied to ``master``, to the ``stable/1.6.X`` + branch, and to the ``stable/1.5.X`` branch. They will trigger the release of + ``1.6.1``, ``1.5.1``, etc. -* Documentation fixes will be applied to trunk, and, if easily backported, to - the ``1.3.X`` branch. +* Documentation fixes will be applied to master, and, if easily backported, to + the ``1.6.X`` branch. Bugfixes may also be backported. .. _release-process: Release process =============== -Django uses a time-based release schedule, with minor (i.e. 1.1, 1.2, etc.) +Django uses a time-based release schedule, with minor (i.e. 1.6, 1.7, etc.) releases every nine months, or more, depending on features. After each release, and after a suitable cooling-off period of a few weeks, the @@ -190,45 +187,56 @@ At the end of phase two, any unfinished "maybe" features will be postponed until the next release. Though it shouldn't happen, any "must-have" features will extend phase two, and thus postpone the final release. -Phase two will culminate with an alpha release. +Phase two will culminate with an alpha release. At this point, the +``stable/A.B.x`` branch will be forked from ``master``. Phase three: bugfixes ~~~~~~~~~~~~~~~~~~~~~ The last third of a release is spent fixing bugs -- no new features will be -accepted during this time. We'll release a beta release about halfway through, -and an rc complete with string freeze two weeks before the end of the schedule. +accepted during this time. We'll try to release a beta release after one month +and a release candidate after two months. + +The release candidate marks the string freeze, and it happens at least two +weeks before the final release. After this point, new translatable strings +must not be added. + +During this phase, committers will be more and more conservative with +backports, to avoid introducing regressions. After the release candidate, only +release blockers and documentation fixes should be backported. + +In parallel to this phase, ``master`` can receive new features, to be released +in the ``A.B+1`` cycle. Bug-fix releases ---------------- -After a minor release (e.g. 1.1), the previous release will go into bugfix +After a minor release (e.g. 1.6), the previous release will go into bugfix mode. -A branch will be created of the form ``branches/releases/1.0.X`` to track -bugfixes to the previous release. Critical bugs fixed on trunk must -*also* be fixed on the bugfix branch; this means that commits need to cleanly -separate bug fixes from feature additions. The developer who commits a fix to -trunk will be responsible for also applying the fix to the current bugfix -branch. Each bugfix branch will have a maintainer who will work with the -committers to keep them honest on backporting bug fixes. +A branch will be created of the form ``stable/1.5.x`` to track bugfixes to the +previous release. Critical bugs fixed on master must *also* be fixed on the +bugfix branch; this means that commits need to cleanly separate bug fixes from +feature additions. The developer who commits a fix to master will be +responsible for also applying the fix to the current bugfix branch. How this all fits together -------------------------- Let's look at a hypothetical example for how this all first together. Imagine, -if you will, a point about halfway between 1.1 and 1.2. At this point, +if you will, a point about halfway between 1.5 and 1.6. At this point, development will be happening in a bunch of places: -* On trunk, development towards 1.2 proceeds with small additions, bugs +* On master, development towards 1.6 proceeds with small additions, bugs fixes, etc. being checked in daily. -* On the branch "branches/releases/1.1.X", fixes for critical bugs found in - the 1.1 release are checked in as needed. At some point, this branch will - be released as "1.1.1", "1.1.2", etc. +* On the branch ``stable/1.5.x``, fixes for critical bugs found in + the 1.5 release are checked in as needed. At some point, this branch will + be released as "1.5.1", "1.5.2", etc. -* On the branch "branches/releases/1.0.X", security fixes are made if - needed and released as "1.0.2", "1.0.3", etc. +* On the branch ``stable/1.4.x``, security fixes are made if + needed and released as "1.4.2", "1.4.3", etc. -* On feature branches, development of major features is done. These - branches will be merged into trunk before the end of phase two. +* Development of major features is done in branches in forks of the main + repository. These branches will be merged into ``master`` before "1.6 + alpha 1". |
