[{"data":1,"prerenderedAt":505},["ShallowReactive",2],{"\u002Fdocs\u002Fdevelopers\u002Fdeveloper-hub":3},{"id":4,"title":5,"body":6,"description":497,"extension":498,"meta":499,"navigation":500,"path":501,"seo":502,"stem":503,"__hash__":504},"docs\u002Fdocs\u002Fdevelopers\u002Fdeveloper-hub.md","Developer Hub",{"type":7,"value":8,"toc":485},"minimark",[9,13,26,31,40,44,49,57,70,81,96,100,121,125,147,151,154,213,216,219,223,230,295,301,305,316,449,475,481],[10,11,5],"h1",{"id":12},"developer-hub",[14,15,16,17,25],"p",{},"The ",[18,19,24],"a",{"href":20,"rel":21,"target":23},"https:\u002F\u002Fhub.leios.dev",[22],"nofollow","_blank","LeiOS Developer Hub"," is where packages for the LeiOS\nrepository are published and reviewed. Developers upload their builds there, and LeiOS admins\nreview stable promotions and cut LeiOS releases.",[27,28,30],"h2",{"id":29},"getting-an-account","Getting an account",[14,32,33,34,39],{},"Self-service sign-up is not available yet. To get an account, ask a LeiOS admin on\n",[18,35,38],{"href":36,"rel":37,"target":23},"https:\u002F\u002Fdiscord.gg\u002F8YC5BXjCc5",[22],"Discord",".",[27,41,43],{"id":42},"concepts","Concepts",[45,46,48],"h3",{"id":47},"publishers","Publishers",[14,50,51,52,56],{},"A ",[53,54,55],"strong",{},"publisher"," owns packages. It can be a person, a team or an organization. A publisher name:",[58,59,60,64,67],"ul",{},[61,62,63],"li",{},"is 2 to 50 characters long,",[61,65,66],{},"uses lowercase letters, digits and hyphens only,",[61,68,69],{},"starts and ends with a letter or digit.",[14,71,72,73,77,78,39],{},"Some names are reserved, including ",[74,75,76],"code",{},"leios"," and ",[74,79,80],{},"leicraft",[14,82,83,84,87,88,91,92,39],{},"Every publisher has an ",[53,85,86],{},"owner",". The owner's name and email address are what the repository\nexpects in the ",[74,89,90],{},"Maintainer"," field of every package the publisher uploads. See\n",[18,93,95],{"href":94},"\u002Fdocs\u002Fdevelopers\u002Fpublishing-packages#the-maintainer-field","Publishing Packages",[45,97,99],{"id":98},"packages","Packages",[14,101,51,102,105,106,109,110,113,114,117,118,39],{},[53,103,104],{},"package"," belongs to a publisher. Its full name is ",[74,107,108],{},"\u003Cpublisher>.\u003Cpackage>",", for example\n",[74,111,112],{},"acme.hello-world",". The package name must match the ",[74,115,116],{},"Package"," field inside your ",[74,119,120],{},".deb",[45,122,124],{"id":123},"releases","Releases",[14,126,51,127,130,131,134,135,138,139,142,143,146],{},[53,128,129],{},"release"," is one version of a package, for example ",[74,132,133],{},"1.2.0-1",". Each release can contain one\nbuild per architecture: ",[74,136,137],{},"amd64",", ",[74,140,141],{},"arm64",", or a single ",[74,144,145],{},"all"," build for architecture-independent\npackages.",[45,148,150],{"id":149},"roles","Roles",[14,152,153],{},"Publisher members have one of four roles:",[155,156,157,170],"table",{},[158,159,160],"thead",{},[161,162,163,167],"tr",{},[164,165,166],"th",{},"Role",[164,168,169],{},"Can do",[171,172,173,184,193,203],"tbody",{},[161,174,175,181],{},[176,177,178],"td",{},[53,179,180],{},"Admin",[176,182,183],{},"Everything a maintainer can, plus edit the publisher, manage its members, and delete packages and releases.",[161,185,186,190],{},[176,187,188],{},[53,189,90],{},[176,191,192],{},"Everything a developer can, plus edit packages and releases.",[161,194,195,200],{},[176,196,197],{},[53,198,199],{},"Developer",[176,201,202],{},"Create packages, publish releases, and request stable promotion.",[161,204,205,210],{},[176,206,207],{},[53,208,209],{},"Viewer",[176,211,212],{},"Read-only access.",[14,214,215],{},"The publisher's owner can do everything, and is the only one who can delete the publisher.",[14,217,218],{},"You can also give someone a role for a single package, for example to let an outside contributor\npublish releases of that package only. If a person has both a publisher role and a package role,\nthe higher one applies.",[27,220,222],{"id":221},"the-repository-api","The Repository API",[14,224,225,226,229],{},"Everything the Hub does goes through the LeiOS Repository API at ",[74,227,228],{},"https:\u002F\u002Fapi.leios.dev",", so you can\nautomate publishing from CI.",[155,231,232,240],{},[158,233,234],{},[161,235,236,238],{},[164,237],{},[164,239],{},[171,241,242,254,268,282],{},[161,243,244,249],{},[176,245,246],{},[53,247,248],{},"Base URL",[176,250,251],{},[74,252,253],{},"https:\u002F\u002Fapi.leios.dev\u002Fv1",[161,255,256,261],{},[176,257,258],{},[53,259,260],{},"Interactive reference",[176,262,263],{},[18,264,267],{"href":265,"rel":266,"target":23},"https:\u002F\u002Fapi.leios.dev\u002Fdocs\u002Fv1",[22],"api.leios.dev\u002Fdocs\u002Fv1",[161,269,270,275],{},[176,271,272],{},[53,273,274],{},"OpenAPI specification",[176,276,277],{},[18,278,281],{"href":279,"rel":280,"target":23},"https:\u002F\u002Fapi.leios.dev\u002Fdocs\u002Fv1\u002Fopenapi",[22],"api.leios.dev\u002Fdocs\u002Fv1\u002Fopenapi",[161,283,284,289],{},[176,285,286],{},[53,287,288],{},"Authentication",[176,290,291,294],{},[74,292,293],{},"Authorization: Bearer \u003Ctoken>",", with a session token or an API key",[14,296,297,298,39],{},"Every response has the same shape: ",[74,299,300],{},"{ \"success\", \"code\", \"message\", \"data\" }",[45,302,304],{"id":303},"api-keys","API keys",[14,306,307,308,311,312,315],{},"For scripts and CI, use an API key instead of your password. API keys start with ",[74,309,310],{},"lra_apikey_",".\nCreate one by logging in and calling ",[74,313,314],{},"\u002Fv1\u002Faccount\u002Fapikeys"," with the session token:",[317,318,323],"pre",{"className":319,"code":320,"language":321,"meta":322,"style":322},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# 1. Log in. The session token is in data.token.\ncurl -s https:\u002F\u002Fapi.leios.dev\u002Fv1\u002Fauth\u002Flogin \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"username\": \"\u003Cusername>\", \"password\": \"\u003Cpassword>\"}'\n\n# 2. Create an API key. The key is in data.token and is shown only once.\ncurl -s https:\u002F\u002Fapi.leios.dev\u002Fv1\u002Faccount\u002Fapikeys \\\n  -H \"Authorization: Bearer \u003Csession token>\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"description\": \"CI uploads\", \"expires_at\": \"90d\"}'\n","bash","",[74,324,325,334,352,370,385,392,398,410,424,437],{"__ignoreMap":322},[326,327,330],"span",{"class":328,"line":329},"line",1,[326,331,333],{"class":332},"sHwdD","# 1. Log in. The session token is in data.token.\n",[326,335,337,341,345,348],{"class":328,"line":336},2,[326,338,340],{"class":339},"sBMFI","curl",[326,342,344],{"class":343},"sfazB"," -s",[326,346,347],{"class":343}," https:\u002F\u002Fapi.leios.dev\u002Fv1\u002Fauth\u002Flogin",[326,349,351],{"class":350},"sTEyZ"," \\\n",[326,353,355,358,362,365,368],{"class":328,"line":354},3,[326,356,357],{"class":343},"  -H",[326,359,361],{"class":360},"sMK4o"," \"",[326,363,364],{"class":343},"Content-Type: application\u002Fjson",[326,366,367],{"class":360},"\"",[326,369,351],{"class":350},[326,371,373,376,379,382],{"class":328,"line":372},4,[326,374,375],{"class":343},"  -d",[326,377,378],{"class":360}," '",[326,380,381],{"class":343},"{\"username\": \"\u003Cusername>\", \"password\": \"\u003Cpassword>\"}",[326,383,384],{"class":360},"'\n",[326,386,388],{"class":328,"line":387},5,[326,389,391],{"emptyLinePlaceholder":390},true,"\n",[326,393,395],{"class":328,"line":394},6,[326,396,397],{"class":332},"# 2. Create an API key. The key is in data.token and is shown only once.\n",[326,399,401,403,405,408],{"class":328,"line":400},7,[326,402,340],{"class":339},[326,404,344],{"class":343},[326,406,407],{"class":343}," https:\u002F\u002Fapi.leios.dev\u002Fv1\u002Faccount\u002Fapikeys",[326,409,351],{"class":350},[326,411,413,415,417,420,422],{"class":328,"line":412},8,[326,414,357],{"class":343},[326,416,361],{"class":360},[326,418,419],{"class":343},"Authorization: Bearer \u003Csession token>",[326,421,367],{"class":360},[326,423,351],{"class":350},[326,425,427,429,431,433,435],{"class":328,"line":426},9,[326,428,357],{"class":343},[326,430,361],{"class":360},[326,432,364],{"class":343},[326,434,367],{"class":360},[326,436,351],{"class":350},[326,438,440,442,444,447],{"class":328,"line":439},10,[326,441,375],{"class":343},[326,443,378],{"class":360},[326,445,446],{"class":343},"{\"description\": \"CI uploads\", \"expires_at\": \"90d\"}",[326,448,384],{"class":360},[14,450,451,454,455,138,458,138,461,138,464,138,467,470,471,474],{},[74,452,453],{},"expires_at"," is one of ",[74,456,457],{},"7d",[74,459,460],{},"30d",[74,462,463],{},"90d",[74,465,466],{},"180d",[74,468,469],{},"365d",", or ",[74,472,473],{},"null"," for no expiry. Store keys like\npasswords, for example as masked CI variables, and use the shortest expiry that works for you.",[476,477,478],"note",{},[14,479,480],{},"The Hub does not have a page for managing API keys yet, and the public package explorer is still\nin development.",[482,483,484],"style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":322,"searchDepth":336,"depth":336,"links":486},[487,488,494],{"id":29,"depth":336,"text":30},{"id":42,"depth":336,"text":43,"children":489},[490,491,492,493],{"id":47,"depth":354,"text":48},{"id":98,"depth":354,"text":99},{"id":123,"depth":354,"text":124},{"id":149,"depth":354,"text":150},{"id":221,"depth":336,"text":222,"children":495},[496],{"id":303,"depth":354,"text":304},"The LeiOS Developer Hub: accounts, publishers, packages, roles, and the API behind it.","md",{},{"title":5},"\u002Fdocs\u002Fdevelopers\u002Fdeveloper-hub",{"title":5,"description":497},"docs\u002Fdevelopers\u002Fdeveloper-hub","l_3lFHQhfoQNu5DR3TaIrbTNPI9JGV3bopeDx4JfPhc",1792353301760]