@@ -26,7 +26,7 @@ function fixture(version = "1.2.3-4") {
2626 for ( const platform of [ ...platforms , null ] ) {
2727 const [ suffix , os , cpu , libc ] = platform ?? [ ] ;
2828 const name = `@github/copilot${ suffix ? `-${ suffix } ` : "" } ` ;
29- const filename = `github-copilot-${ version } ${ suffix ? `-${ suffix } ` : "" } .tgz` ;
29+ const filename = `npm- github-copilot-${ version } ${ suffix ? `-${ suffix } ` : "" } .tgz` ;
3030 const source = join ( root , filename ) ;
3131 const packageDir = join ( root , "work" , "package" ) ;
3232 mkdirSync ( packageDir , { recursive : true } ) ;
@@ -54,6 +54,15 @@ function fixture(version = "1.2.3-4") {
5454 } ;
5555}
5656
57+ function attachLegacyTarballs ( f ) {
58+ const launcher = f . release . assets . find ( ( asset ) => asset . name === `npm-github-copilot-${ f . release . tag_name . slice ( 1 ) } .tgz` ) ;
59+ for ( const platform of [ ...platforms . map ( ( [ suffix ] ) => `-${ suffix } ` ) , "" ] ) {
60+ const name = `github-copilot-${ f . release . tag_name . slice ( 1 ) } ${ platform } .tgz` ;
61+ cpSync ( join ( f . root , launcher . name ) , join ( f . root , name ) ) ;
62+ f . release . assets . push ( { ...launcher , name } ) ;
63+ }
64+ }
65+
5766async function exercise ( options = { } ) {
5867 const f = fixture ( options . version ) ;
5968 const published = [ ] ;
@@ -64,7 +73,8 @@ async function exercise(options = {}) {
6473 const run = ( tool , args ) => {
6574 if ( tool === "gh" && args [ 0 ] === "api" ) return JSON . stringify ( f . release ) ;
6675 if ( tool === "gh" && args [ 0 ] === "release" ) {
67- for ( const asset of f . release . assets ) {
76+ assert . equal ( args [ args . indexOf ( "--pattern" ) + 1 ] , "npm-github-copilot-*.tgz" ) ;
77+ for ( const asset of f . release . assets . filter ( ( entry ) => entry . name . startsWith ( "npm-github-copilot-" ) && entry . name . endsWith ( ".tgz" ) ) ) {
6878 const source = join ( f . root , asset . name ) ;
6979 cpSync ( source , join ( args . at ( - 1 ) , asset . name ) ) ;
7080 }
@@ -98,7 +108,43 @@ test("publishes all eight platforms before launcher with prerelease tag", async
98108 const { published } = await exercise ( { eventId : "1234" , eventPrerelease : "true" } ) ;
99109 assert . equal ( published . length , 9 ) ;
100110 assert . ok ( published . every ( ( args ) => args [ args . indexOf ( "--tag" ) + 1 ] === "prerelease" ) ) ;
101- assert . match ( published . at ( - 1 ) [ 1 ] , / g i t h u b - c o p i l o t - 1 \. 2 \. 3 - 4 \. t g z $ / ) ;
111+ assert . match ( published . at ( - 1 ) [ 1 ] , / n p m - g i t h u b - c o p i l o t - 1 \. 2 \. 3 - 4 \. t g z $ / ) ;
112+ } ) ;
113+
114+ test ( "ignores the nine old launcher-manifest tarballs and publishes only the new npm packages" , async ( ) => {
115+ const { published } = await exercise ( { mutate : attachLegacyTarballs } ) ;
116+ assert . equal ( published . length , 9 ) ;
117+ assert . ok ( published . every ( ( args ) => args [ 1 ] . split ( "/" ) . at ( - 1 ) . startsWith ( "npm-github-copilot-" ) ) ) ;
118+ } ) ;
119+
120+ test ( "rejects an old release with only the nine legacy tarballs, including manual recovery" , async ( ) => {
121+ await assert . rejects ( exercise ( {
122+ mutate : ( f ) => {
123+ attachLegacyTarballs ( f ) ;
124+ f . release . assets = f . release . assets . filter ( ( asset ) => ! asset . name . startsWith ( "npm-github-copilot-" ) ) ;
125+ } ,
126+ } ) , ( error ) => {
127+ assert . match ( error . message , / n i n e e x p e c t e d n p m t a r b a l l s / ) ;
128+ assert . deepEqual ( error . published , [ ] ) ;
129+ return true ;
130+ } ) ;
131+ } ) ;
132+
133+ test ( "rejects a new platform asset whose manifest is actually the old launcher" , async ( ) => {
134+ await assert . rejects ( exercise ( {
135+ mutate : ( f ) => {
136+ attachLegacyTarballs ( f ) ;
137+ const platformAsset = f . release . assets . find ( ( asset ) => asset . name === "npm-github-copilot-1.2.3-4-linux-x64.tgz" ) ;
138+ const launcher = f . release . assets . find ( ( asset ) => asset . name === "npm-github-copilot-1.2.3-4.tgz" ) ;
139+ cpSync ( join ( f . root , launcher . name ) , join ( f . root , platformAsset . name ) ) ;
140+ platformAsset . size = launcher . size ;
141+ platformAsset . digest = launcher . digest ;
142+ } ,
143+ } ) , ( error ) => {
144+ assert . match ( error . message , / P a c k a g e i d e n t i t y o r r e p o s i t o r y m i s m a t c h f o r @ g i t h u b \/ c o p i l o t - l i n u x - x 6 4 / ) ;
145+ assert . deepEqual ( error . published , [ ] ) ;
146+ return true ;
147+ } ) ;
102148} ) ;
103149
104150test ( "a matching existing package is skipped on a partial rerun" , async ( ) => {
@@ -131,7 +177,7 @@ test("rejects a registry integrity mismatch before any publish", async () => {
131177} ) ;
132178
133179test ( "rejects invalid launcher dependencies and platform metadata before publishing" , async ( ) => {
134- for ( const filename of [ "github-copilot-1.2.3-4.tgz" , "github-copilot-1.2.3-4-linuxmusl-x64.tgz" ] ) {
180+ for ( const filename of [ "npm- github-copilot-1.2.3-4.tgz" , "npm- github-copilot-1.2.3-4-linuxmusl-x64.tgz" ] ) {
135181 await assert . rejects ( exercise ( {
136182 mutate : ( f ) => {
137183 const work = join ( f . root , "work" ) ;
@@ -166,6 +212,7 @@ test("rejects incomplete assets and incorrect digests before any publish", async
166212 ( f ) => { f . release . assets . pop ( ) ; } ,
167213 ( f ) => { f . release . assets [ 0 ] . digest = `sha256:${ "0" . repeat ( 64 ) } ` ; } ,
168214 ( f ) => { f . release . assets [ 0 ] . name = "unexpected.tgz" ; } ,
215+ ( f ) => { f . release . assets . push ( { ...f . release . assets [ 0 ] , name : "npm-github-copilot-1.2.3-4-unknown.tgz" } ) ; } ,
169216 ] ) {
170217 await assert . rejects ( exercise ( { mutate } ) , ( error ) => {
171218 assert . deepEqual ( error . published , [ ] ) ;
0 commit comments