[firefox] Add automation (#67)
Signed-off-by: Benji Visser <benji@093b.org>
This commit is contained in:
503
releases/firefox.json
Normal file
503
releases/firefox.json
Normal file
@@ -0,0 +1,503 @@
|
||||
{
|
||||
"108.0.2": "2023-01-05",
|
||||
"108.0.1": "2022-12-16",
|
||||
"108.0": "2022-12-13",
|
||||
"102.6.0": "2022-12-13",
|
||||
"107.0.1": "2022-11-29",
|
||||
"107.0": "2022-11-15",
|
||||
"102.5.0": "2022-11-15",
|
||||
"106.0.5": "2022-11-04",
|
||||
"106.0.4": "2022-11-03",
|
||||
"106.0.3": "2022-10-31",
|
||||
"106.0.2": "2022-10-26",
|
||||
"106.0.1": "2022-10-20",
|
||||
"106.0": "2022-10-18",
|
||||
"102.4.0": "2022-10-18",
|
||||
"105.0.3": "2022-10-07",
|
||||
"105.0.2": "2022-10-04",
|
||||
"105.0.1": "2022-09-23",
|
||||
"105.0": "2022-09-20",
|
||||
"102.3.0": "2022-09-20",
|
||||
"104.0.2": "2022-09-06",
|
||||
"104.0.1": "2022-08-30",
|
||||
"91.13.0": "2022-08-23",
|
||||
"104.0": "2022-08-23",
|
||||
"102.2.0": "2022-08-23",
|
||||
"103.0.2": "2022-08-09",
|
||||
"103.0.1": "2022-08-01",
|
||||
"91.12.0": "2022-07-26",
|
||||
"103.0": "2022-07-26",
|
||||
"102.1.0": "2022-07-26",
|
||||
"102.0.1": "2022-07-06",
|
||||
"91.11.0": "2022-06-28",
|
||||
"102.0": "2022-06-28",
|
||||
"101.0.1": "2022-06-09",
|
||||
"91.10.0": "2022-05-31",
|
||||
"101.0": "2022-05-31",
|
||||
"91.9.1": "2022-05-20",
|
||||
"100.0.2": "2022-05-20",
|
||||
"100.0.1": "2022-05-16",
|
||||
"91.9.0": "2022-05-03",
|
||||
"100.0": "2022-05-03",
|
||||
"99.0.1": "2022-04-12",
|
||||
"99.0": "2022-04-05",
|
||||
"91.8.0": "2022-04-05",
|
||||
"98.0.2": "2022-03-23",
|
||||
"98.0.1": "2022-03-14",
|
||||
"91.7.1": "2022-03-14",
|
||||
"98.0": "2022-03-08",
|
||||
"91.7.0": "2022-03-08",
|
||||
"97.0.2": "2022-03-05",
|
||||
"91.6.1": "2022-03-05",
|
||||
"97.0.1": "2022-02-17",
|
||||
"97.0": "2022-02-08",
|
||||
"91.6.0": "2022-02-08",
|
||||
"96.0.3": "2022-01-27",
|
||||
"91.5.1": "2022-01-27",
|
||||
"96.0.2": "2022-01-20",
|
||||
"96.0.1": "2022-01-14",
|
||||
"96.0": "2022-01-11",
|
||||
"91.5.0": "2022-01-11",
|
||||
"95.0.2": "2021-12-19",
|
||||
"95.0.1": "2021-12-16",
|
||||
"91.4.1": "2021-12-16",
|
||||
"95.0": "2021-12-07",
|
||||
"91.4.0": "2021-12-07",
|
||||
"94.0.2": "2021-11-22",
|
||||
"94.0.1": "2021-11-04",
|
||||
"94.0": "2021-11-02",
|
||||
"91.3.0": "2021-11-02",
|
||||
"93.0": "2021-10-05",
|
||||
"91.2.0": "2021-10-05",
|
||||
"78.15.0": "2021-10-05",
|
||||
"92.0.1": "2021-09-23",
|
||||
"92.0": "2021-09-07",
|
||||
"91.1.0": "2021-09-07",
|
||||
"78.14.0": "2021-09-07",
|
||||
"91.0.2": "2021-08-24",
|
||||
"91.0.1": "2021-08-17",
|
||||
"91.0": "2021-08-10",
|
||||
"78.13.0": "2021-08-10",
|
||||
"90.0.2": "2021-07-22",
|
||||
"90.0.1": "2021-07-19",
|
||||
"90.0": "2021-07-13",
|
||||
"78.12.0": "2021-07-13",
|
||||
"89.0.2": "2021-06-23",
|
||||
"89.0.1": "2021-06-17",
|
||||
"89.0": "2021-06-01",
|
||||
"78.11.0": "2021-06-01",
|
||||
"88.0.1": "2021-05-05",
|
||||
"78.10.1": "2021-05-04",
|
||||
"88.0": "2021-04-19",
|
||||
"78.10.0": "2021-04-19",
|
||||
"87.0": "2021-03-23",
|
||||
"78.9.0": "2021-03-23",
|
||||
"86.0.1": "2021-03-11",
|
||||
"86.0": "2021-02-23",
|
||||
"78.8.0": "2021-02-23",
|
||||
"85.0.2": "2021-02-09",
|
||||
"85.0.1": "2021-02-05",
|
||||
"78.7.1": "2021-02-05",
|
||||
"85.0": "2021-01-26",
|
||||
"78.7.0": "2021-01-26",
|
||||
"84.0.2": "2021-01-06",
|
||||
"78.6.1": "2021-01-06",
|
||||
"84.0.1": "2020-12-22",
|
||||
"84.0": "2020-12-15",
|
||||
"78.6.0": "2020-12-15",
|
||||
"83.0": "2020-11-17",
|
||||
"78.5.0": "2020-11-17",
|
||||
"82.0.3": "2020-11-10",
|
||||
"78.4.1": "2020-11-10",
|
||||
"82.0.2": "2020-10-28",
|
||||
"82.0.1": "2020-10-27",
|
||||
"82.0": "2020-10-20",
|
||||
"78.4.0": "2020-10-20",
|
||||
"81.0.2": "2020-10-13",
|
||||
"81.0.1": "2020-10-01",
|
||||
"78.3.1": "2020-10-01",
|
||||
"81.0": "2020-09-22",
|
||||
"78.3.0": "2020-09-22",
|
||||
"80.0.1": "2020-09-01",
|
||||
"80.0": "2020-08-25",
|
||||
"78.2.0": "2020-08-25",
|
||||
"68.12.0": "2020-08-25",
|
||||
"79.0": "2020-07-28",
|
||||
"78.1.0": "2020-07-28",
|
||||
"68.11.0": "2020-07-28",
|
||||
"78.0.2": "2020-07-09",
|
||||
"78.0.1": "2020-07-01",
|
||||
"78.0": "2020-06-30",
|
||||
"68.10.0": "2020-06-30",
|
||||
"77.0.1": "2020-06-03",
|
||||
"77.0": "2020-06-02",
|
||||
"68.9.0": "2020-06-02",
|
||||
"76.0.1": "2020-05-08",
|
||||
"76.0": "2020-05-05",
|
||||
"68.8.0": "2020-05-05",
|
||||
"75.0": "2020-04-07",
|
||||
"68.7.0": "2020-04-07",
|
||||
"74.0.1": "2020-04-03",
|
||||
"68.6.1": "2020-04-03",
|
||||
"74.0": "2020-03-10",
|
||||
"68.6.0": "2020-03-10",
|
||||
"73.0.1": "2020-02-18",
|
||||
"73.0": "2020-02-11",
|
||||
"68.5.0": "2020-02-11",
|
||||
"72.0.2": "2020-01-20",
|
||||
"68.4.2": "2020-01-20",
|
||||
"72.0.1": "2020-01-08",
|
||||
"68.4.1": "2020-01-08",
|
||||
"72.0": "2020-01-07",
|
||||
"68.4.0": "2020-01-07",
|
||||
"71.0": "2019-12-03",
|
||||
"68.3.0": "2019-12-03",
|
||||
"70.0.1": "2019-10-31",
|
||||
"70.0": "2019-10-22",
|
||||
"68.2.0": "2019-10-22",
|
||||
"69.0.3": "2019-10-10",
|
||||
"69.0.2": "2019-10-03",
|
||||
"69.0.1": "2019-09-18",
|
||||
"69.0": "2019-09-03",
|
||||
"68.1.0": "2019-09-03",
|
||||
"60.9.0": "2019-09-03",
|
||||
"68.0.2": "2019-08-14",
|
||||
"68.0.1": "2019-07-18",
|
||||
"68.0": "2019-07-09",
|
||||
"60.8.0": "2019-07-09",
|
||||
"67.0.4": "2019-06-20",
|
||||
"60.7.2": "2019-06-20",
|
||||
"67.0.3": "2019-06-18",
|
||||
"60.7.1": "2019-06-18",
|
||||
"67.0.2": "2019-06-11",
|
||||
"67.0.1": "2019-06-04",
|
||||
"67.0": "2019-05-21",
|
||||
"60.7.0": "2019-05-21",
|
||||
"60.6.3": "2019-05-08",
|
||||
"66.0.5": "2019-05-07",
|
||||
"66.0.4": "2019-05-05",
|
||||
"60.6.2": "2019-05-05",
|
||||
"66.0.3": "2019-04-10",
|
||||
"66.0.2": "2019-03-27",
|
||||
"66.0.1": "2019-03-22",
|
||||
"60.6.1": "2019-03-22",
|
||||
"66.0": "2019-03-19",
|
||||
"60.6.0": "2019-03-19",
|
||||
"65.0.2": "2019-02-28",
|
||||
"60.5.2": "2019-02-22",
|
||||
"65.0.1": "2019-02-12",
|
||||
"60.5.1": "2019-02-12",
|
||||
"65.0": "2019-01-29",
|
||||
"60.5.0": "2019-01-29",
|
||||
"64.0.2": "2019-01-09",
|
||||
"64.0": "2018-12-11",
|
||||
"60.4.0": "2018-12-11",
|
||||
"63.0.3": "2018-11-15",
|
||||
"63.0.1": "2018-10-31",
|
||||
"63.0": "2018-10-23",
|
||||
"60.3.0": "2018-10-23",
|
||||
"62.0.3": "2018-10-02",
|
||||
"60.2.2": "2018-10-02",
|
||||
"62.0.2": "2018-09-21",
|
||||
"60.2.1": "2018-09-21",
|
||||
"62.0": "2018-09-05",
|
||||
"60.2.0": "2018-09-05",
|
||||
"61.0.2": "2018-08-08",
|
||||
"61.0.1": "2018-07-05",
|
||||
"61.0": "2018-06-26",
|
||||
"60.1.0": "2018-06-26",
|
||||
"52.9.0": "2018-06-26",
|
||||
"60.0.2": "2018-06-06",
|
||||
"52.8.1": "2018-06-06",
|
||||
"60.0.1": "2018-05-16",
|
||||
"60.0": "2018-05-09",
|
||||
"52.8.0": "2018-05-09",
|
||||
"59.0.3": "2018-04-30",
|
||||
"52.7.4": "2018-04-30",
|
||||
"59.0.2": "2018-03-26",
|
||||
"52.7.3": "2018-03-26",
|
||||
"59.0.1": "2018-03-16",
|
||||
"52.7.2": "2018-03-16",
|
||||
"52.7.1": "2018-03-14",
|
||||
"59.0": "2018-03-13",
|
||||
"52.7.0": "2018-03-13",
|
||||
"58.0.2": "2018-02-07",
|
||||
"58.0.1": "2018-01-29",
|
||||
"58.0": "2018-01-23",
|
||||
"52.6.0": "2018-01-23",
|
||||
"57.0.4": "2018-01-04",
|
||||
"57.0.3": "2017-12-28",
|
||||
"52.5.3": "2017-12-28",
|
||||
"57.0.2": "2017-12-07",
|
||||
"52.5.2": "2017-12-07",
|
||||
"57.0.1": "2017-11-29",
|
||||
"57.0": "2017-11-14",
|
||||
"52.5.0": "2017-11-14",
|
||||
"56.0.2": "2017-10-26",
|
||||
"56.0.1": "2017-10-09",
|
||||
"52.4.1": "2017-10-09",
|
||||
"56.0": "2017-09-28",
|
||||
"52.4.0": "2017-09-28",
|
||||
"55.0.3": "2017-08-25",
|
||||
"55.0.2": "2017-08-16",
|
||||
"55.0.1": "2017-08-10",
|
||||
"55.0": "2017-08-08",
|
||||
"52.3.0": "2017-08-08",
|
||||
"54.0.1": "2017-06-29",
|
||||
"52.2.1": "2017-06-29",
|
||||
"54.0": "2017-06-13",
|
||||
"52.2.0": "2017-06-13",
|
||||
"53.0.3": "2017-05-19",
|
||||
"52.1.2": "2017-05-19",
|
||||
"53.0.2": "2017-05-05",
|
||||
"52.1.1": "2017-05-05",
|
||||
"53.0": "2017-04-19",
|
||||
"52.1.0": "2017-04-19",
|
||||
"45.9.0": "2017-04-19",
|
||||
"52.0.2": "2017-03-28",
|
||||
"52.0.1": "2017-03-17",
|
||||
"52.0": "2017-03-07",
|
||||
"45.8.0": "2017-03-07",
|
||||
"51.0.1": "2017-01-26",
|
||||
"51.0": "2017-01-24",
|
||||
"45.7.0": "2017-01-24",
|
||||
"50.1.0": "2016-12-13",
|
||||
"45.6.0": "2016-12-13",
|
||||
"50.0.2": "2016-11-30",
|
||||
"45.5.1": "2016-11-30",
|
||||
"50.0.1": "2016-11-28",
|
||||
"50.0": "2016-11-15",
|
||||
"45.5.0": "2016-11-15",
|
||||
"47.0.2": "2016-11-01",
|
||||
"49.0.2": "2016-10-20",
|
||||
"49.0.1": "2016-09-23",
|
||||
"49.0": "2016-09-20",
|
||||
"45.4.0": "2016-09-20",
|
||||
"48.0.2": "2016-08-24",
|
||||
"48.0.1": "2016-08-18",
|
||||
"48.0": "2016-08-02",
|
||||
"45.3.0": "2016-08-02",
|
||||
"47.0.1": "2016-06-28",
|
||||
"47.0": "2016-06-07",
|
||||
"45.2.0": "2016-06-07",
|
||||
"46.0.1": "2016-05-03",
|
||||
"45.1.1": "2016-05-03",
|
||||
"46.0": "2016-04-26",
|
||||
"38.8.0": "2016-04-26",
|
||||
"45.0.2": "2016-04-11",
|
||||
"45.0.1": "2016-03-16",
|
||||
"38.7.1": "2016-03-16",
|
||||
"45.0": "2016-03-08",
|
||||
"38.7.0": "2016-03-08",
|
||||
"44.0.2": "2016-02-11",
|
||||
"38.6.1": "2016-02-11",
|
||||
"44.0.1": "2016-02-08",
|
||||
"44.0": "2016-01-26",
|
||||
"38.6.0": "2016-01-26",
|
||||
"43.0.4": "2016-01-06",
|
||||
"43.0.3": "2015-12-28",
|
||||
"43.0.2": "2015-12-22",
|
||||
"38.5.2": "2015-12-22",
|
||||
"38.5.1": "2015-12-21",
|
||||
"43.0.1": "2015-12-18",
|
||||
"43.0": "2015-12-15",
|
||||
"38.5.0": "2015-12-15",
|
||||
"42.0": "2015-11-03",
|
||||
"38.4.0": "2015-11-03",
|
||||
"41.0.2": "2015-10-15",
|
||||
"41.0.1": "2015-09-30",
|
||||
"41.0": "2015-09-22",
|
||||
"38.3.0": "2015-09-22",
|
||||
"40.0.3": "2015-08-27",
|
||||
"38.2.1": "2015-08-27",
|
||||
"40.0.2": "2015-08-13",
|
||||
"40.0": "2015-08-11",
|
||||
"38.2.0": "2015-08-11",
|
||||
"39.0.3": "2015-08-06",
|
||||
"38.1.1": "2015-08-06",
|
||||
"39.0": "2015-07-02",
|
||||
"38.1.0": "2015-07-02",
|
||||
"31.8.0": "2015-07-02",
|
||||
"38.0.5": "2015-06-02",
|
||||
"38.0.1": "2015-05-14",
|
||||
"38.0": "2015-05-12",
|
||||
"31.7.0": "2015-05-12",
|
||||
"37.0.2": "2015-04-20",
|
||||
"37.0.1": "2015-04-03",
|
||||
"37.0": "2015-03-31",
|
||||
"31.6.0": "2015-03-31",
|
||||
"36.0.4": "2015-03-21",
|
||||
"31.5.3": "2015-03-21",
|
||||
"36.0.3": "2015-03-20",
|
||||
"31.5.2": "2015-03-20",
|
||||
"36.0.1": "2015-03-05",
|
||||
"36.0": "2015-02-24",
|
||||
"31.5.0": "2015-02-24",
|
||||
"35.0.1": "2015-01-26",
|
||||
"35.0": "2015-01-13",
|
||||
"31.4.0": "2015-01-13",
|
||||
"34.0.5": "2014-12-01",
|
||||
"34.0": "2014-12-01",
|
||||
"31.3.0": "2014-12-01",
|
||||
"33.1.1": "2014-11-14",
|
||||
"33.1": "2014-11-10",
|
||||
"33.0.3": "2014-11-06",
|
||||
"33.0.2": "2014-10-28",
|
||||
"33.0.1": "2014-10-24",
|
||||
"31.2.0": "2014-10-14",
|
||||
"33.0": "2014-10-13",
|
||||
"32.0.3": "2014-09-24",
|
||||
"24.8.1": "2014-09-24",
|
||||
"31.1.1": "2014-09-23",
|
||||
"32.0.2": "2014-09-18",
|
||||
"32.0.1": "2014-09-12",
|
||||
"32.0": "2014-09-02",
|
||||
"24.8.0": "2014-09-02",
|
||||
"31.1.0": "2014-09-01",
|
||||
"31.0": "2014-07-22",
|
||||
"24.7.0": "2014-07-22",
|
||||
"30.0": "2014-06-10",
|
||||
"24.6.0": "2014-06-10",
|
||||
"29.0.1": "2014-05-09",
|
||||
"29.0": "2014-04-29",
|
||||
"24.5.0": "2014-04-29",
|
||||
"28.0": "2014-03-18",
|
||||
"24.4.0": "2014-03-18",
|
||||
"27.0.1": "2014-02-13",
|
||||
"27.0": "2014-02-04",
|
||||
"24.3.0": "2014-02-04",
|
||||
"26.0": "2013-12-10",
|
||||
"24.2.0": "2013-12-10",
|
||||
"25.0.1": "2013-11-15",
|
||||
"24.1.1": "2013-11-15",
|
||||
"17.0.11": "2013-11-15",
|
||||
"25.0": "2013-10-29",
|
||||
"24.1.0": "2013-10-29",
|
||||
"17.0.10": "2013-10-29",
|
||||
"24.0": "2013-09-17",
|
||||
"17.0.9": "2013-09-17",
|
||||
"23.0.1": "2013-08-16",
|
||||
"23.0": "2013-08-06",
|
||||
"17.0.8": "2013-08-06",
|
||||
"22.0": "2013-06-25",
|
||||
"17.0.7": "2013-06-25",
|
||||
"21.0": "2013-05-14",
|
||||
"17.0.6": "2013-05-14",
|
||||
"20.0.1": "2013-04-11",
|
||||
"20.0": "2013-04-02",
|
||||
"17.0.5": "2013-04-02",
|
||||
"19.0.2": "2013-03-07",
|
||||
"17.0.4": "2013-03-07",
|
||||
"19.0.1": "2013-02-27",
|
||||
"19.0": "2013-02-19",
|
||||
"17.0.3": "2013-02-19",
|
||||
"18.0.2": "2013-02-05",
|
||||
"18.0.1": "2013-01-18",
|
||||
"18.0": "2013-01-08",
|
||||
"17.0.2": "2013-01-08",
|
||||
"10.0.12": "2013-01-08",
|
||||
"17.0.1": "2012-11-30",
|
||||
"17.0": "2012-11-20",
|
||||
"10.0.11": "2012-11-20",
|
||||
"16.0.2": "2012-10-26",
|
||||
"10.0.10": "2012-10-26",
|
||||
"10.0.9": "2012-10-12",
|
||||
"16.0.1": "2012-10-11",
|
||||
"16.0": "2012-10-09",
|
||||
"10.0.8": "2012-10-09",
|
||||
"15.0.1": "2012-09-06",
|
||||
"15.0": "2012-08-28",
|
||||
"10.0.7": "2012-08-28",
|
||||
"14.0.1": "2012-07-17",
|
||||
"10.0.6": "2012-07-17",
|
||||
"13.0.1": "2012-06-15",
|
||||
"13.0": "2012-06-05",
|
||||
"10.0.5": "2012-06-05",
|
||||
"12.0": "2012-04-24",
|
||||
"10.0.4": "2012-04-24",
|
||||
"3.6.28": "2012-03-13",
|
||||
"11.0": "2012-03-13",
|
||||
"10.0.3": "2012-03-13",
|
||||
"3.6.27": "2012-02-17",
|
||||
"10.0.2": "2012-02-16",
|
||||
"10.0.1": "2012-02-10",
|
||||
"3.6.26": "2012-01-31",
|
||||
"10.0": "2012-01-31",
|
||||
"9.0.1": "2011-12-21",
|
||||
"9.0": "2011-12-20",
|
||||
"3.6.25": "2011-12-20",
|
||||
"8.0.1": "2011-11-21",
|
||||
"8.0": "2011-11-08",
|
||||
"3.6.24": "2011-11-08",
|
||||
"7.0.1": "2011-09-29",
|
||||
"7.0": "2011-09-27",
|
||||
"3.6.23": "2011-09-27",
|
||||
"6.0.2": "2011-09-06",
|
||||
"3.6.22": "2011-09-06",
|
||||
"6.0.1": "2011-08-30",
|
||||
"3.6.21": "2011-08-30",
|
||||
"6.0": "2011-08-16",
|
||||
"3.6.20": "2011-08-16",
|
||||
"5.0.1": "2011-07-11",
|
||||
"3.6.19": "2011-07-11",
|
||||
"5.0": "2011-06-21",
|
||||
"3.6.18": "2011-06-21",
|
||||
"4.0.1": "2011-04-28",
|
||||
"3.6.17": "2011-04-28",
|
||||
"3.5.19": "2011-04-28",
|
||||
"4.0": "2011-03-22",
|
||||
"3.6.16": "2011-03-22",
|
||||
"3.5.18": "2011-03-22",
|
||||
"3.6.15": "2011-03-04",
|
||||
"3.6.14": "2011-03-01",
|
||||
"3.5.17": "2011-03-01",
|
||||
"3.6.13": "2010-12-09",
|
||||
"3.5.16": "2010-12-09",
|
||||
"3.6.12": "2010-10-27",
|
||||
"3.5.15": "2010-10-27",
|
||||
"3.6.11": "2010-10-19",
|
||||
"3.5.14": "2010-10-19",
|
||||
"3.6.10": "2010-09-15",
|
||||
"3.5.13": "2010-09-15",
|
||||
"3.6.9": "2010-09-07",
|
||||
"3.5.12": "2010-09-07",
|
||||
"3.6.8": "2010-07-23",
|
||||
"3.6.7": "2010-07-20",
|
||||
"3.5.11": "2010-07-20",
|
||||
"3.6.6": "2010-06-26",
|
||||
"3.6.4": "2010-06-22",
|
||||
"3.5.10": "2010-06-22",
|
||||
"3.6.3": "2010-04-01",
|
||||
"3.5.9": "2010-03-30",
|
||||
"3.0.19": "2010-03-30",
|
||||
"3.6.2": "2010-03-22",
|
||||
"3.5.8": "2010-02-17",
|
||||
"3.0.18": "2010-02-17",
|
||||
"3.6": "2010-01-21",
|
||||
"3.5.7": "2010-01-05",
|
||||
"3.0.17": "2010-01-05",
|
||||
"3.5.6": "2009-12-15",
|
||||
"3.0.16": "2009-12-15",
|
||||
"3.5.5": "2009-11-05",
|
||||
"3.5.4": "2009-10-27",
|
||||
"3.0.15": "2009-10-27",
|
||||
"3.5.3": "2009-09-09",
|
||||
"3.0.14": "2009-09-09",
|
||||
"3.5.2": "2009-08-03",
|
||||
"3.0.13": "2009-08-03",
|
||||
"3.0.12": "2009-07-21",
|
||||
"3.5.1": "2009-07-16",
|
||||
"3.5": "2009-06-30",
|
||||
"3.0.11": "2009-06-11",
|
||||
"3.0.10": "2009-04-27",
|
||||
"3.0.9": "2009-04-21",
|
||||
"3.0.8": "2009-03-27",
|
||||
"3.0.7": "2009-03-04",
|
||||
"3.0.6": "2009-02-03",
|
||||
"3.0.5": "2008-12-16",
|
||||
"3.0.4": "2008-11-12",
|
||||
"3.0.3": "2008-09-26",
|
||||
"3.0.2": "2008-09-23",
|
||||
"3.0.1": "2008-07-16",
|
||||
"3.0": "2008-06-17"
|
||||
}
|
||||
153
src/firefox.py
Normal file
153
src/firefox.py
Normal file
@@ -0,0 +1,153 @@
|
||||
import json
|
||||
from typing import Tuple
|
||||
from datetime import datetime
|
||||
import re
|
||||
import requests
|
||||
import urllib.request
|
||||
from bs4 import BeautifulSoup
|
||||
import concurrent.futures
|
||||
|
||||
"""Fetch Firefox versions with their dates from https://www.mozilla.org/en-US/firefox/releases/"""
|
||||
URL = "https://www.mozilla.org/en-US/firefox/releases/"
|
||||
PRODUCT = "firefox"
|
||||
|
||||
DATE_REGEX = r"(January|Jan|February|Feb|March|Mar|April|Apr|May|June|Jun|July|Jul|August|Aug|September|Sept|October|Oct|November|Nov|December|Dec)\s+\d{1,2}(st|nd|rd|th)?,\s+\d{4}"
|
||||
VERSION_REGEX = r"\d+(\.\d+)*"
|
||||
|
||||
class UnsupportedReleasePageError(Exception):
|
||||
"Raised when a firefox release page is not supported"
|
||||
pass
|
||||
|
||||
class InvalidPageVariantError(Exception):
|
||||
"Raised when an invalid variant is passed to get_version_and_date"
|
||||
pass
|
||||
|
||||
def format_date(unformatted_date: str) -> str:
|
||||
""" Format date from July 11, 2002 to 2002-07-11 """
|
||||
date = re.sub(r'(\d)(st|nd|rd|th)', r'\1', unformatted_date)
|
||||
formats = ["%b %d, %Y", "%B %d, %Y"]
|
||||
for f in formats:
|
||||
try:
|
||||
return datetime.strptime(date, f).strftime("%Y-%m-%d")
|
||||
except ValueError:
|
||||
pass
|
||||
return ""
|
||||
|
||||
def get_version_and_date_varant_1(soup: BeautifulSoup) -> Tuple[str, str]:
|
||||
""" Version matching for firefox versions >= 28.0 (usually) """
|
||||
# get version
|
||||
version = soup.find("div", class_="c-release-version").get_text()
|
||||
|
||||
# get date
|
||||
unformatted_date = soup.find("p", class_="c-release-date").get_text()
|
||||
date = format_date(unformatted_date)
|
||||
|
||||
return (version, date)
|
||||
|
||||
def get_version_and_date_variant_2(soup: BeautifulSoup) -> Tuple[str, str]:
|
||||
""" Version matching for firefox versions >= 10.0 (usually) """
|
||||
release_info = soup.find("h2").find("small").text
|
||||
|
||||
# get version
|
||||
version_match = re.search(VERSION_REGEX, soup.select('div#nav-access a')[0].get("href"))
|
||||
if version_match is None:
|
||||
raise InvalidPageVariantError("Unable to find version")
|
||||
version = version_match.group()
|
||||
|
||||
# get date
|
||||
unformatted_date_match = re.search(DATE_REGEX, release_info)
|
||||
if unformatted_date_match is None:
|
||||
raise InvalidPageVariantError("Unable to find date")
|
||||
unformatted_date = unformatted_date_match.group()
|
||||
date = format_date(unformatted_date)
|
||||
|
||||
return (version, date)
|
||||
|
||||
def get_version_and_date_variant_3(soup: BeautifulSoup) -> Tuple[str, str]:
|
||||
""" Version matching for firefox versions >= 3.0 (usually) """
|
||||
release_info = soup.select('div#main-feature p em')[0].get_text()
|
||||
|
||||
# get version
|
||||
version_match = re.search(VERSION_REGEX, release_info)
|
||||
if version_match is None:
|
||||
raise InvalidPageVariantError("Unable to find version")
|
||||
version = version_match.group()
|
||||
|
||||
# get date
|
||||
unformatted_date_match = re.search(DATE_REGEX, release_info)
|
||||
if unformatted_date_match is None:
|
||||
raise InvalidPageVariantError("Unable to find date")
|
||||
unformatted_date = unformatted_date_match.group()
|
||||
date = format_date(unformatted_date)
|
||||
|
||||
return (version, date)
|
||||
|
||||
def get_version_and_date(release_page: str, release_version: str) -> Tuple[str, str]:
|
||||
""" Get version and date from the given release page """
|
||||
major = int(release_version.split(".")[0])
|
||||
|
||||
# firefox release pages for versions <3.0 don't include release dates so we
|
||||
# can't match these versions for now.
|
||||
# example: https://www.mozilla.org/en-US/firefox/2.0/releasenotes/
|
||||
if major < 3:
|
||||
raise UnsupportedReleasePageError("Unsupported release page: %s" % release_page)
|
||||
|
||||
# Firefox release pages come in 3 different variants. Unforunately, there is no
|
||||
# consistent way to determine which variant a page is (say, by version number), so
|
||||
# we have to try each variant until we find one that works.
|
||||
functions = [get_version_and_date_varant_1, get_version_and_date_variant_2, get_version_and_date_variant_3]
|
||||
soup = make_bs_request(release_page)
|
||||
|
||||
for function in functions:
|
||||
try:
|
||||
return function(soup)
|
||||
except (InvalidPageVariantError, AttributeError, IndexError):
|
||||
pass
|
||||
|
||||
raise UnsupportedReleasePageError("Unable to find version and date for %s" % release_page)
|
||||
|
||||
def make_bs_request(url: str) -> BeautifulSoup:
|
||||
""" Make a request to the given url and return a BeautifulSoup object """
|
||||
headers = {"user-agent": "mozilla"}
|
||||
req = urllib.request.Request(url, headers=headers)
|
||||
res = urllib.request.urlopen(req, timeout=5)
|
||||
return BeautifulSoup(res.read(), features="html5lib")
|
||||
|
||||
def fetch_releases():
|
||||
releases = {}
|
||||
soup = make_bs_request(URL)
|
||||
|
||||
ff_releases = soup.find_all("ol", class_="c-release-list")
|
||||
with concurrent.futures.ThreadPoolExecutor() as executor:
|
||||
future_to_url = {
|
||||
executor.submit(
|
||||
get_version_and_date,
|
||||
requests.compat.urljoin(URL, p.get("href")),
|
||||
p.get_text()): p.get("href") for p in ff_releases[0].find_all("a")
|
||||
}
|
||||
|
||||
for future in concurrent.futures.as_completed(future_to_url):
|
||||
try:
|
||||
(version, date) = future.result()
|
||||
print("%s: %s" % (version, date))
|
||||
releases[version] = date
|
||||
except UnsupportedReleasePageError:
|
||||
print("Unsupported release page: %s" % future_to_url[future])
|
||||
|
||||
return releases
|
||||
|
||||
def main():
|
||||
print(f"::group::{PRODUCT}")
|
||||
|
||||
releases = fetch_releases()
|
||||
with open(f"releases/{PRODUCT}.json", "w") as f:
|
||||
f.write(json.dumps(dict(
|
||||
# sort by date then version (desc)
|
||||
sorted(releases.items(), key=lambda x: (x[1], x[0]), reverse=True)
|
||||
), indent=2))
|
||||
|
||||
print("::endgroup::")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user